首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

简略的Jax-WS WebService实现

2013-12-10 
简单的Jax-WS WebService实现目录?1???? 定义Service2???? 服务端发布Service3???? 客户端访问Service4???

简单的Jax-WS WebService实现

目录

?

1???? 定义Service

2???? 服务端发布Service

3???? 客户端访问Service

4???? 基于Spring的Jax-ws WebService

4.1???? Service定义

4.2???? 服务端发布Service

4.3???? 客户端获取Service

?

?????? Jax-ws是WebService的一种规范。

1?????? 定义Service

?????? Jax-ws的WebService定义是通过注解进行的,我们必须在其WebService类的接口上使用@WebService注解进行标记。

?

@WebServicepublic interface HelloWorld {    public String sayHi(String who);   }

????????

如上,我们把HelloWorld定义为一个WebService,其对应有一个sayHi操作。其对应的实现类如下:?

?

public class HelloWorldImpl implements HelloWorld {    @Override   public String sayHi(String who) {      return "Hi, " + who;   } }

2?????? 服务端发布Service

?????? 对于Jax-ws WebService而言,发布Service有两种方式。

第一种:

?

public class Server {    private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";      public static void main(String args[]) {      HelloWorld hw = new HelloWorldImpl();      Endpoint.publish(ADDRESS, hw);   }   }

?

第二种:?

?

public class Server {private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";public static void main(String args[]) {HelloWorld hw = new HelloWorldImpl();JaxWsServerFactoryBean jwsFactory = new JaxWsServerFactoryBean();jwsFactory.setAddress(ADDRESS);//指定WebService的发布地址jwsFactory.setServiceClass(HelloWorld.class);//WebService对应的类型jwsFactory.setServiceBean(hw);//WebService对应的实现对象jwsFactory.create();}}

?

?????? 发布之后我们就可以通过发布地址?wsdl查看WebService的定义了(WSDL是WebService Document Location的简称,即WebService文档位置的意思)。通过在浏览器输入http://localhost:8080/test/jaxws/services/HelloWorld?wsdl我们可以看到如下内容:

?

This XML file does not appear to have any style information associatedwith it. The document tree is shown below.<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"name="HelloWorldImplService" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/"><wsdl:types><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"elementFormDefault="unqualified" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/"version="1.0"><xs:element name="sayHi" type="tns:sayHi" /><xs:element name="sayHiResponse" type="tns:sayHiResponse" /><xs:complexType name="sayHi"><xs:sequence><xs:element minOccurs="0" name="arg0" type="xs:string" /></xs:sequence></xs:complexType><xs:complexType name="sayHiResponse"><xs:sequence><xs:element minOccurs="0" name="return" type="xs:string" /></xs:sequence></xs:complexType></xs:schema></wsdl:types><wsdl:message name="sayHiResponse"><wsdl:part element="tns:sayHiResponse" name="parameters"></wsdl:part></wsdl:message><wsdl:message name="sayHi"><wsdl:part element="tns:sayHi" name="parameters"></wsdl:part></wsdl:message><wsdl:portType name="HelloWorld"><wsdl:operation name="sayHi"><wsdl:input message="tns:sayHi" name="sayHi"></wsdl:input><wsdl:output message="tns:sayHiResponse" name="sayHiResponse"></wsdl:output></wsdl:operation></wsdl:portType><wsdl:binding name="HelloWorldImplServiceSoapBinding"type="tns:HelloWorld"><soap:binding style="document"transport="http://schemas.xmlsoap.org/soap/http" /><wsdl:operation name="sayHi"><soap:operation soapAction="" style="document" /><wsdl:input name="sayHi"><soap:body use="literal" /></wsdl:input><wsdl:output name="sayHiResponse"><soap:body use="literal" /></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="HelloWorldImplService"><wsdl:port binding="tns:HelloWorldImplServiceSoapBinding"name="HelloWorldImplPort"><soap:address location="http://localhost:8080/test/jaxws/services/HelloWorld" /></wsdl:port></wsdl:service></wsdl:definitions>

???

?????? 我们可以看到在上面我们的sayHi操作的参数who变成了arg0,这是因为接口在被编译为class文件的时候不能保存参数名,有时候这会影响可读性。如果需要参数名显示的可读性强一些的话,我们可以使用@WebParam来指定,如:

?

@WebService(serviceName="!@#$%^", name="123456")public interface HelloWorld {    public String sayHi(@WebParam(name="who") String who);   }

?

@WebService的serviceName可以用来指定service的名称,默认情况下如果Service是通过Endpoint.publish()方法发布的则serviceName为实现类的简单名称+Service(如HelloWorldImplService),如果是通过JaxWsServerFactoryBean的create方法发布的则为接口的简单名称+Service(如HelloWorldService)。name属性可以用来指定service对应的portName,默认情况下如果Service是通过Endpoint.publish()方法发布的则portName为实现类的简单名称+Port(如HelloWorldImplPort),如果是通过JaxWsServerFactoryBean的create方法发布的则为接口的简单名称+Port(如HelloWorldPort)。?

3?????? 客户端访问Service

类似于WebService简单实现里面的ClientProxyFactoryBean,在使用Jax-ws时我们可以通过JaxWsProxyFactoryBean来访问服务,如:

?

public class Client {private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";public static void main(String args[]) {JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();jwpFactory.setAddress(ADDRESS);jwpFactory.setServiceClass(HelloWorld.class);HelloWorld hw = (HelloWorld)jwpFactory.create();String response = hw.sayHi("world");System.out.println(response);}}

?

除了上面的方式之外,我们还可以这样获取Service:

?

//第一个参数为服务发布的targetNameSpace,可以通过查看对应的wsdl文件获得,默认是发布Service所在包的包名倒过来的形式;第二个参数是serviceNameprivate final static QName SERVICE_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldService");//第一个参数是服务发布的targetNameSpace,第二个参数是portNameprivate final static QName PORT_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldPort");//服务发布的地址private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";public static void main(String args[]) {Service service = Service.create(SERVICE_NAME);//根据portName、服务发布地址、数据绑定类型创建一个Port。service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, ADDRESS);//默认是SOAP1.1Binding//获取服务HelloWorld hw = service.getPort(HelloWorld.class);String response = hw.sayHi("world");System.out.println(response);}??

?

?????? 在上面的代码中我们只需要有一个Service实例,就能通过它来获取真正的WebService,所以,我们如果把上面的代码改成如下形式也是可以的。?

?

//第一个参数为服务发布的targetNameSpace,可以通过查看对应的wsdl文件获得,默认是发布Service所在包的包名倒过来的形式;第二个参数是serviceNameprivate final static QName SERVICE_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldService");//第一个参数是服务发布的targetNameSpace,第二个参数是portNameprivate final static QName PORT_NAME = new QName("http://jaxws.sample.cxftest.tiantian.com/", "HelloWorldPort");//服务发布的地址private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";public static void main(String args[]) {Service service = Service.create(null);//根据portName、服务发布地址、数据绑定类型创建一个Port。service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, ADDRESS);//默认是SOAP1.1Binding//获取服务HelloWorld hw = service.getPort(HelloWorld.class);String response = hw.sayHi("world");System.out.println(response);}

?

???????

上面这种通过Service来获取WebService的方法是不适用前面介绍的简单WebService实现的,即不适用获取通过ServerFactoryBean发布的WebService。

?

4?????? 基于Spring的Jax-ws WebService

4.1???? Service定义?

?????? Service定义跟之前的定义是一样的。?

4.2???? 服务端发布Service

?????? 首先在web.xml文件中定义一个CXFServlet,用于发布和拦截WebService请求。

?

<!-- Jax-ws实现 --><servlet><display-name>jaxws-cxf</display-name><servlet-name>jaxws-cxf</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><load-on-startup>1</load-on-startup><init-param><param-name>config-location</param-name><param-value>WEB-INF/jaxws-cxf-servlet.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>jaxws-cxf</servlet-name><url-pattern>/jaxws/services/*</url-pattern></servlet-mapping>

??

?????? 接下来在我们的WebService配置文件里面定义我们的WebService发布,即CXFServlet指定的jaxws-cxf-servlet.xml文件(默认是cxf-servlet.xml文件)。这里我们定义如下:

?

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><!-- 相当于使用Endpoint.publish()进行服务发布 --><jaxws:endpoint address="/HelloWorld" implementorserviceserviceBean="#hw"/><!-- 普通bean对象 --><bean id="hw" style="margin: 0cm 0cm 0pt;">?????? 客户端可以直接从Spring的bean配置文件中把WebService配置为一个个普通的Spring bean对象进行使用。只是在定义之前需要往bean配置文件中引入Jax-ws的命名空间。这里我们在classpath下定义一个jaxws-cxf-client.xml文件,其内容如下所示:

?

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><jaxws:client id="hw"address="http://localhost:8080/test/jaxws/services/HelloWorld"service/><jaxws:client id="hw2"address="http://localhost:8080/test/jaxws/services/HelloWorld2"servicestyle="text-align: left; margin: 0cm 0cm 0pt;">?

?????? 之后我们就可以把这些定义好的WebService当做一个普通的bean对象来使用了,如:

?

public class SpringClient {public static void main(String args[]) {ApplicationContext context = new ClassPathXmlApplicationContext("jaxws-cxf-client.xml");accessService(context, "hw");accessService(context, "hw2");accessService(context, "hw3");accessService(context, "hw4");}private static void accessService(ApplicationContext context, String beanName) {HelloWorld hw = context.getBean(beanName, HelloWorld.class);System.out.println(hw.sayHi("world"));}}

?

??

?

?

热点排行