JAX-WS教程
欢迎使用JAX-WS教程。
Web服务在客户端-服务器模型上工作,它们通过网络进行通信。
服务器端组件提供服务所在的端点URL,客户端应用程序可以调用不同的方法。
Web服务有两种类型:
- SOAP Web服务
- 宁静的Web服务
JAX-WS教程
在本JAX-WS教程中,我们将使用JAX-WS创建基于SOAP的Web服务。
但是首先,我们将介绍SOAP Web服务中使用的一些专业术语。
肥皂
SOAP代表简单对象访问协议。
SOAP是用于设计和开发Web服务的基于XML的行业标准协议。
由于它基于XML,因此与平台和语言无关。
因此,我们的服务器可以基于JAVA,客户端可以基于.NET,PHP等,反之亦然。
WSDL
WSDL代表Web服务描述语言。
WSDL是基于XML的文档,提供有关Web服务的技术详细信息。
WSDL文档中的一些有用信息包括:方法名称,端口类型,服务端点,绑定,方法参数等。
UDDI
UDDI是通用描述,发现和集成的首字母缩写。
UDDI是Web服务的目录,客户端应用程序可以其中查找Web服务。
Web服务可以注册到UDDI服务器,并使它们可用于客户端应用程序。
Web服务的优势
Web服务的一些优点是:
互操作性:因为Web服务通过网络工作并且使用XML技术进行通信,所以可以使用支持Web服务开发的任何编程语言来开发它。
可重用性:一个Web服务可以同时被许多客户端应用程序使用。
例如,我们可以公开用于股票技术分析的Web服务,并且所有银行和金融机构都可以使用它。松散耦合:Web服务客户端代码与服务器代码完全独立,因此我们在应用程序中实现了松散耦合。
这导致易于维护并且易于扩展。易于部署和集成
可以同时运行多个服务版本。
JAX-WS
JAX-WS代表XML Web Services的Java API。
JAX-WS是基于XML的Java API,用于构建Web服务服务器和客户端应用程序。
它是标准Java API的一部分,因此我们不需要包含其他任何可以使用它的东西。
JAX-WS示例
现在我们已经了解了Web服务的术语,让我们继续创建JAX-WS Web服务。
我们将创建一个Web服务,该服务将公开添加,删除和获取人员对象的方法。
因此,首先,我们将为数据创建一个模型bean。
Person.java
package com.theitroad.jaxws.beans; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = -5577579081118070434L; private String name; private int age; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString(){ return id+"::"+name+"::"+age; } }
现在,我们将不得不创建一个接口,在该接口中声明将在我们的JAX-WS示例Web服务中公开的方法。
PersonService.java
package com.theitroad.jaxws.service; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import com.theitroad.jaxws.beans.Person; @WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public interface PersonService { @WebMethod public boolean addPerson(Person p); @WebMethod public boolean deletePerson(int id); @WebMethod public Person getPerson(int id); @WebMethod public Person[] getAllPersons(); }
注意,JAX-WS API使用了@WebService和@SOAPBinding注释。
我们可以采用RPC样式或者Document样式创建SOAP Web服务。
我们可以使用这些样式中的任何一种来创建Web服务,不同之处在于WSDL文件的生成方式。
现在,我们将编写实现类,如下所示。
PersonServiceImpl.java
package com.theitroad.jaxws.service; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.jws.WebService; import com.theitroad.jaxws.beans.Person; @WebService(endpointInterface = "com.theitroad.jaxws.service.PersonService") public class PersonServiceImpl implements PersonService { private static Map<Integer,Person> persons = new HashMap<Integer,Person>(); @Override public boolean addPerson(Person p) { if(persons.get(p.getId()) != null) return false; persons.put(p.getId(), p); return true; } @Override public boolean deletePerson(int id) { if(persons.get(id) == null) return false; persons.remove(id); return true; } @Override public Person getPerson(int id) { return persons.get(id); } @Override public Person[] getAllPersons() { Set<Integer> ids = persons.keySet(); Person[] p = new Person[ids.size()]; int i=0; for(Integer id : ids){ p[i] = persons.get(id); i++; } return p; } }
最重要的部分是@WebService批注,其中我们将提供endpointInterface值作为Web服务的接口。
这样,当Web服务方法被调用时,JAX-WS知道要用于实现的类。
我们的网络服务业务逻辑已经准备就绪,让我们继续使用JAX-WS Endpoint类进行发布。
SOAPPublisher.java
package com.theitroad.jaxws.service; import javax.xml.ws.Endpoint; public class SOAPPublisher { public static void main(String[] args) { Endpoint.publish("https://localhost:8888/ws/person", new PersonServiceImpl()); } }
只需运行以上程序,您的Web服务就会在程序中的给定端点上发布。
我们可以通过在端点URL上添加?wsdl来访问其WSDL文档,如下图所示。
这是WSDL代码,我们在编写客户端代码时将使用其中的一些值。
person.wsdl
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI (https://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><!-- Generated by JAX-WS RI (https://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><definitions xmlns:wsu="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="https://www.w3.org/ns/ws-policy" xmlns:wsp1_2="https://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="https://www.w3.org/2007/05/addressing/metadata" xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="https://service.jaxws.theitroad.local/" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns="https://schemas.xmlsoap.org/wsdl/" targetNamespace="https://service.jaxws.theitroad.local/" name="PersonServiceImplService"> <types> <xsd:schema> <xsd:import namespace="https://service.jaxws.theitroad.local/" schemaLocation="https://localhost:8888/ws/person?xsd=1"></xsd:import> </xsd:schema> </types> <message name="addPerson"> <part name="arg0" type="tns:person"></part> </message> <message name="addPersonResponse"> <part name="return" type="xsd:boolean"></part> </message> <message name="deletePerson"> <part name="arg0" type="xsd:int"></part> </message> <message name="deletePersonResponse"> <part name="return" type="xsd:boolean"></part> </message> <message name="getPerson"> <part name="arg0" type="xsd:int"></part> </message> <message name="getPersonResponse"> <part name="return" type="tns:person"></part> </message> <message name="getAllPersons"></message> <message name="getAllPersonsResponse"> <part name="return" type="tns:personArray"></part> </message> <portType name="PersonService"> <operation name="addPerson"> <input wsam:Action="https://service.jaxws.theitroad.local/PersonService/addPersonRequest" message="tns:addPerson"></input> <output wsam:Action="https://service.jaxws.theitroad.local/PersonService/addPersonResponse" message="tns:addPersonResponse"></output> </operation> <operation name="deletePerson"> <input wsam:Action="https://service.jaxws.theitroad.local/PersonService/deletePersonRequest" message="tns:deletePerson"></input> <output wsam:Action="https://service.jaxws.theitroad.local/PersonService/deletePersonResponse" message="tns:deletePersonResponse"></output> </operation> <operation name="getPerson"> <input wsam:Action="https://service.jaxws.theitroad.local/PersonService/getPersonRequest" message="tns:getPerson"></input> <output wsam:Action="https://service.jaxws.theitroad.local/PersonService/getPersonResponse" message="tns:getPersonResponse"></output> </operation> <operation name="getAllPersons"> <input wsam:Action="https://service.jaxws.theitroad.local/PersonService/getAllPersonsRequest" message="tns:getAllPersons"></input> <output wsam:Action="https://service.jaxws.theitroad.local/PersonService/getAllPersonsResponse" message="tns:getAllPersonsResponse"></output> </operation> </portType> <binding name="PersonServiceImplPortBinding" type="tns:PersonService"> <soap:binding transport="https://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding> <operation name="addPerson"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </input> <output> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </output> </operation> <operation name="deletePerson"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </input> <output> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </output> </operation> <operation name="getPerson"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </input> <output> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </output> </operation> <operation name="getAllPersons"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </input> <output> <soap:body use="literal" namespace="https://service.jaxws.theitroad.local/"></soap:body> </output> </operation> </binding> <service name="PersonServiceImplService"> <port name="PersonServiceImplPort" binding="tns:PersonServiceImplPortBinding"> <soap:address location="https://localhost:8888/ws/person"></soap:address> </port> </service> </definitions>
这是一个客户端程序,我们其中调用我们的JAX-WS示例Web服务。
SOAPPublisherClient.java
package com.theitroad.jaxws.service; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.theitroad.jaxws.beans.Person; public class SOAPPublisherClient { public static void main(String[] args) throws MalformedURLException { URL wsdlURL = new URL("https://localhost:8888/ws/person?wsdl"); //check above URL in browser, you should see WSDL file //creating QName using targetNamespace and name QName qname = new QName("https://service.jaxws.theitroad.local/", "PersonServiceImplService"); Service service = Service.create(wsdlURL, qname); //We need to pass interface and model beans to client PersonService ps = service.getPort(PersonService.class); Person p1 = new Person(); p1.setName("hyman"); p1.setId(1); p1.setAge(30); Person p2 = new Person(); p2.setName("Meghna"); p2.setId(2); p2.setAge(25); //add person System.out.println("Add Person Status="+ps.addPerson(p1)); System.out.println("Add Person Status="+ps.addPerson(p2)); //get person System.out.println(ps.getPerson(1)); //get all persons System.out.println(Arrays.asList(ps.getAllPersons())); //delete person System.out.println("Delete Person Status="+ps.deletePerson(2)); //get all persons System.out.println(Arrays.asList(ps.getAllPersons())); } }
当我们执行上面的JAX-WS客户端程序时,我们得到此输出。
Add Person Status=true Add Person Status=true 1::hyman::30 [1::hyman::30, 2::Meghna::25] Delete Person Status=true [1::hyman::30]
当我再次运行程序时,我们得到此输出。
Add Person Status=false Add Person Status=true 1::hyman::30 [1::hyman::30, 2::Meghna::25] Delete Person Status=true [1::hyman::30]
请注意,在第二次运行中,添加人状态为false,因为它已在第一次运行中添加。
JAX-WS客户端程序
如果您看上面的程序,我们正在使用服务器代码本身。
但是,Web服务仅公开WSDL,而第三方应用程序无权访问这些类。
因此,在这种情况下,我们可以使用" wsimport"实用程序来生成客户端存根。
该实用程序随JDK的标准安装一起提供。
下图显示了运行该实用程序时得到的所有Java类。
只需将这些类复制到您的客户端项目中,唯一的变化就是我们获取PersonService
实例的方式。
下面是用于此的程序,输出将与上面的客户端程序相同。
请注意,使用了" PersonServiceImplService"类,并使用了" getPersonServiceImplPort"方法来获取PersonService实例。
TestPersonService.java
package com.theitroad.jaxws.service.test; import java.util.Arrays; import com.theitroad.jaxws.service.Person; import com.theitroad.jaxws.service.PersonService; import com.theitroad.jaxws.service.PersonServiceImplService; public class TestPersonService { public static void main(String[] args) { PersonServiceImplService serviceImpl = new PersonServiceImplService(); PersonService service = serviceImpl.getPersonServiceImplPort(); Person p1 = new Person(); p1.setName("hyman"); p1.setId(1); p1.setAge(30); Person p2 = new Person(); p2.setName("Meghna"); p2.setId(2); p2.setAge(25); System.out.println("Add Person Status="+service.addPerson(p1)); System.out.println("Add Person Status="+service.addPerson(p2)); //get person System.out.println(service.getPerson(1)); //get all persons System.out.println(Arrays.asList(service.getAllPersons())); //delete person System.out.println("Delete Person Status="+service.deletePerson(2)); //get all persons System.out.println(Arrays.asList(service.getAllPersons())); } }