君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

目录

 

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注解进行标记。

 

Java代码  
  1. @WebService  
  2. public interface HelloWorld {  
  3.    
  4.    public String sayHi(String who);  
  5.      
  6. }  

        

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

 

Java代码  
  1. public class HelloWorldImpl implements HelloWorld {  
  2.    
  3.    @Override  
  4.    public String sayHi(String who) {  
  5.       return "Hi, " + who;  
  6.    }  
  7.    
  8. }  

2       服务端发布Service

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

第一种:

 

Java代码  
  1. public class Server {  
  2.    
  3.    private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
  4.      
  5.    public static void main(String args[]) {  
  6.       HelloWorld hw = new HelloWorldImpl();  
  7.       Endpoint.publish(ADDRESS, hw);  
  8.    }  
  9.      
  10. }  

 

第二种: 

 

Java代码  
  1. public class Server {  
  2.   
  3.     private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
  4.       
  5.     public static void main(String args[]) {  
  6.         HelloWorld hw = new HelloWorldImpl();  
  7.         JaxWsServerFactoryBean jwsFactory = new JaxWsServerFactoryBean();  
  8.         jwsFactory.setAddress(ADDRESS); //指定WebService的发布地址  
  9.         jwsFactory.setServiceClass(HelloWorld.class);//WebService对应的类型  
  10.         jwsFactory.setServiceBean(hw);//WebService对应的实现对象  
  11.         jwsFactory.create();  
  12.     }  
  13.       
  14. }  

 

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

 

Xml代码  
  1. This XML file does not appear to have any style information associated  
  2. with it. The document tree is shown below.  
  3. <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
  4.     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"  
  5.     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"  
  6.     name="HelloWorldImplService" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/">  
  7.     <wsdl:types>  
  8.         <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  
  9.             xmlns:tns="http://jaxws.sample.cxftest.tiantian.com/"  
  10.             elementFormDefault="unqualified" targetNamespace="http://jaxws.sample.cxftest.tiantian.com/"  
  11.             version="1.0">  
  12.             <xs:element name="sayHi" type="tns:sayHi" />  
  13.             <xs:element name="sayHiResponse" type="tns:sayHiResponse" />  
  14.             <xs:complexType name="sayHi">  
  15.                 <xs:sequence>  
  16.                     <xs:element minOccurs="0" name="arg0" type="xs:string" />  
  17.                 </xs:sequence>  
  18.             </xs:complexType>  
  19.             <xs:complexType name="sayHiResponse">  
  20.                 <xs:sequence>  
  21.                     <xs:element minOccurs="0" name="return" type="xs:string" />  
  22.                 </xs:sequence>  
  23.             </xs:complexType>  
  24.         </xs:schema>  
  25.     </wsdl:types>  
  26.     <wsdl:message name="sayHiResponse">  
  27.         <wsdl:part element="tns:sayHiResponse" name="parameters"></wsdl:part>  
  28.     </wsdl:message>  
  29.     <wsdl:message name="sayHi">  
  30.         <wsdl:part element="tns:sayHi" name="parameters"></wsdl:part>  
  31.     </wsdl:message>  
  32.     <wsdl:portType name="HelloWorld">  
  33.         <wsdl:operation name="sayHi">  
  34.             <wsdl:input message="tns:sayHi" name="sayHi"></wsdl:input>  
  35.             <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"></wsdl:output>  
  36.         </wsdl:operation>  
  37.     </wsdl:portType>  
  38.     <wsdl:binding name="HelloWorldImplServiceSoapBinding"  
  39.         type="tns:HelloWorld">  
  40.         <soap:binding style="document"  
  41.             transport="http://schemas.xmlsoap.org/soap/http" />  
  42.         <wsdl:operation name="sayHi">  
  43.             <soap:operation soapAction="" style="document" />  
  44.             <wsdl:input name="sayHi">  
  45.                 <soap:body use="literal" />  
  46.             </wsdl:input>  
  47.             <wsdl:output name="sayHiResponse">  
  48.                 <soap:body use="literal" />  
  49.             </wsdl:output>  
  50.         </wsdl:operation>  
  51.     </wsdl:binding>  
  52.     <wsdl:service name="HelloWorldImplService">  
  53.         <wsdl:port binding="tns:HelloWorldImplServiceSoapBinding"  
  54.             name="HelloWorldImplPort">  
  55.             <soap:address location="http://localhost:8080/test/jaxws/services/HelloWorld" />  
  56.         </wsdl:port>  
  57.     </wsdl:service>  
  58. </wsdl:definitions>  

   

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

 

Java代码  
  1. @WebService(serviceName="!@#$%^", name="123456")  
  2. public interface HelloWorld {  
  3.    
  4.    public String sayHi(@WebParam(name="who") String who);  
  5.      
  6. }  

 

@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来访问服务,如:

 

Java代码  
  1. public class Client {  
  2.   
  3.     private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";  
  4.       
  5.     public static void main(String args[]) {  
  6.         JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();  
  7.         jwpFactory.setAddress(ADDRESS);  
  8.         jwpFactory.setServiceClass(HelloWorld.class);  
  9.         HelloWorld hw = (HelloWorld)jwpFactory.create();  
  10.         String response = hw.sayHi("world");  
  11.         System.out.println(response);  
  12.     }  
  13.       
  14. }  

 

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

 

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

 

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

 

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

 

       

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

 

4       基于Spring的Jax-ws WebService

4.1     Service定义 

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

4.2     服务端发布Service

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

 

Xml代码  
  1. <!-- Jax-ws实现 -->  
  2. <servlet>  
  3.     <display-name>jaxws-cxf</display-name>  
  4.     <servlet-name>jaxws-cxf</servlet-name>  
  5.     <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
  6.     <load-on-startup>1</load-on-startup>  
  7.     <init-param>  
  8.         <param-name>config-location</param-name>  
  9.         <param-value>WEB-INF/jaxws-cxf-servlet.xml</param-value>  
  10.     </init-param>  
  11. </servlet>  
  12.   
  13. <servlet-mapping>  
  14.     <servlet-name>jaxws-cxf</servlet-name>  
  15.     <url-pattern>/jaxws/services/*</url-pattern>  
  16. </servlet-mapping>  

  

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

 

Xml代码  
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
  3.     xsi:schemaLocation="  
  4. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  5. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
  6.   
  7.     <!-- 相当于使用Endpoint.publish()进行服务发布 -->  
  8.     <jaxws:endpoint address="/HelloWorld" implementorClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
  9.   
  10.     <!-- 相当于使用JaxWsServerFactoryBean进行服务发布 -->  
  11.     <jaxws:server address="/HelloWorld2" serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
  12.       
  13.     <!-- JaxWsServerFactoryBean使用外部bean作为服务进行发布 -->  
  14.     <jaxws:server address="/HelloWorld3" serviceBean="#hw"/>  
  15.     <!-- 普通bean对象 -->  
  16.     <bean id="hw" class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
  17.       
  18.     <!-- JaxWsServerFactoryBean使用内部bean作为服务进行发布 -->  
  19.     <jaxws:server address="/HelloWorld4">  
  20.         <jaxws:serviceBean>  
  21.             <bean class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>  
  22.         </jaxws:serviceBean>  
  23.     </jaxws:server>  
  24.   
  25. </beans>  

4.3     客户端获取Service

       客户端可以直接从Spring的bean配置文件中把WebService配置为一个个普通的Spring bean对象进行使用。只是在定义之前需要往bean配置文件中引入Jax-ws的命名空间。这里我们在classpath下定义一个jaxws-cxf-client.xml文件,其内容如下所示:

 

Xml代码  
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
  3.     xsi:schemaLocation="  
  4. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  5. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
  6.   
  7.     <jaxws:client id="hw"  
  8.         address="http://localhost:8080/test/jaxws/services/HelloWorld"  
  9.         serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld" />  
  10.   
  11.     <jaxws:client id="hw2"  
  12.         address="http://localhost:8080/test/jaxws/services/HelloWorld2"  
  13.         serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
  14.           
  15.     <jaxws:client id="hw3"  
  16.         address="http://localhost:8080/test/jaxws/services/HelloWorld3"  
  17.         serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
  18.           
  19.     <jaxws:client id="hw4"  
  20.         address="http://localhost:8080/test/jaxws/services/HelloWorld4"  
  21.         serviceClass="com.tiantian.cxftest.sample.jaxws.HelloWorld"/>  
  22.   
  23. </beans>  

 

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

 

Java代码  
  1. public class SpringClient {  
  2.   
  3.     public static void main(String args[]) {  
  4.         ApplicationContext context = new ClassPathXmlApplicationContext("jaxws-cxf-client.xml");  
  5.         accessService(context, "hw");  
  6.         accessService(context, "hw2");  
  7.         accessService(context, "hw3");  
  8.         accessService(context, "hw4");  
  9.     }  
  10.       
  11.     private static void accessService(ApplicationContext context, String beanName) {  
  12.         HelloWorld hw = context.getBean(beanName, HelloWorld.class);  
  13.         System.out.println(hw.sayHi("world"));  
  14.     }  
  15.       
  16. }  

  

 http://haohaoxuexi.iteye.com/blog/1985995

posted on 2013-12-13 18:12  刺猬的温驯  阅读(881)  评论(0)    收藏  举报