CXF+Web Service入门实例展示

Web Service的三个基本技术:
1.SOAP  --  web Service的基本通信协议,是一种规范,用来定义SOAP消息的xml格式
2.WSDL  --  是一个用来描述Web服务和说明如何与Web服务通信的XML语言,
       WSDL是Web Service的描述语言,用于描述Web Service的服务,接口绑定等,为用户提供详细的接口说明书
3.UUID  --  即统一描述,发现和集成协议,UUID实现了一组可公开访问的接口,通过这些接口,网络服务可以

       以向服务信息库注册其服务信息,服务需求者可以找到分散在世界各地的网络服


(二)代理工厂,安全验证,数据绑定

 

代理工厂

1.服务端:ServerFactoryBean,JaxWsServerFactoryBean 用于服务端调用.前者针对POJO,后者针对JAX-WS,他们用于生成服务端的EndPoint,暴露出服务接口

2.客户端:ClientProxyFactoryBean,JaxWsProxyFactoryBean 用于客户端调用.前者针对POJO,后者针对JAX-WS,他用于在客户端生成Web Service的代理proxy

3.除了这些Factory,CXF客户端还有ClientFactoryBean,JaxWsClientFactoryBean,这两个Factory生成的不是Web Service的代理,而是一个Endpoint,提供一些更该机的功能.

 

安全验证

Apache WSS4J(WebService Security For Java) 实现了java语言的 WS-Security.WSS4J依赖于SAAJ.CXF中使用拦截器机制完成WSS4J功能的支持.只需要初始化WSS4JInInterceptor(对应还有一个WSS4JOutInterceptor)实例并添加相关信息即可.CXF2.1.x之后的版本可以完成SAAJInInterceptor(对应的一个SAAJOutInterceptor)拦截器的自动注册,否则需要再注册一下SAAJ拦截器.

1.在spring.xml中配置WSS4J输入拦截器

 

Xml代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
  2.    <map>  
  3.       <entry key="xx" value="xx"/>  
  4.    </map>  
  5. </bean>  
  6. </span>  

在接口服务里面加入关系

Xml代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><jaxws:inInterceptors>  
  2.     <ref bean="wss4jInInterceptor" />  
  3. </jaxws:inInterceptors>  
  4. </span>  

下面是服务器端具体密码回调处理类,它负责接收并处理客户端提交的用户名和密码,这个方法没有返回值,显示,如果验证失败,抛出异常表示.

Java代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;">import java.io.IOException;  
  2. import javax.security.auth.callback.Callback;  
  3. import javax.security.auth.callback.CallbackHandler;  
  4. import javax.security.auth.callback.UnsupportedCallbackException;  
  5. import org.apache.ws.security.WSConstants;  
  6. import org.apache.ws.security.WSPasswordCallback;  
  7. import org.apache.ws.security.WSSecurityException;  
  8.   
  9. public class ServerPasswordCallbackHandler implements CallbackHandler {  
  10.   
  11.     public final static String USER = "liu";  
  12.     public final static String PASSWORD = "lius";//设置用户名密码  
  13.     public void handle(Callback[] callbacks) throws IOException,  
  14.             UnsupportedCallbackException {  
  15.         WSPasswordCallback wspassCallback = (WSPasswordCallback) callbacks[0];  
  16.         System.out.println(wspassCallback.getIdentifier() + "\t"  
  17.                 + wspassCallback.getPassword());  
  18.           
  19.         if(WSConstants.PASSWORD_TEXT.equals(wspassCallback.getPasswordType())){  
  20.             if (wspassCallback.getIdentifier().equals(USER)  
  21.                     && wspassCallback.getPassword().equals(PASSWORD)) {  
  22.                 System.out.println(".................验证通过!");     
  23.                 System.out.println(".................identifier = " + USER);     
  24.                 System.out.println(".................password = " + PASSWORD);   
  25.             } else {  
  26.                 throw new WSSecurityException("............未通过验证!");  
  27.             }  
  28.         } else {  
  29.             //密码使用MD5密文发送  
  30.             System.out.println(wspassCallback.getIdentifier());   
  31.             wspassCallback.setPassword(PASSWORD);  
  32.         }  
  33.     }  
  34. }  
  35. </span>  

2.客户端实现:在spring.xml中配置WSS4J输出拦截器

Xml代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><bean id="wss4jOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
  2.    <map>  
  3.       <entry key="xx" value="xx"/>  
  4.    </map>  
  5. </bean></span>  

在服务接口里加入关系

Xml代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><jaxws:outInterceptors>  
  2.     <ref bean="wss4jOutInterceptor" />  
  3. </jaxws:outInterceptors</span>  

这里使用了WSS4J输出拦截器,因为要将用户名和密码输出到服务器进行验证处理.另外与服务端不同的是多了一个user参数初始化WSS4J的输出拦截器,用于初始化用户名,这是一个必选,稍后将在下面的客户端密码回调处理类进行重新设定值

Java代码   收藏代码
  1. <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;">import java.io.IOException;  
  2. import javax.security.auth.callback.Callback;  
  3. import javax.security.auth.callback.CallbackHandler;  
  4. import javax.security.auth.callback.UnsupportedCallbackException;  
  5. import org.apache.ws.security.WSPasswordCallback;  
  6.   
  7. public class ClientPasswordCallbackHandler implements CallbackHandler{  
  8.     public final static String USER = "liu";  
  9.     public final static String PASSWORD = "lius";//设置用户名密码  
  10.     public void handle(Callback[] callbacks) throws IOException,  
  11.             UnsupportedCallbackException {  
  12.         WSPasswordCallback wspassCallback = (WSPasswordCallback)callbacks[0];  
  13.         wspassCallback.setIdentifier(USER);  
  14.         wspassCallback.setPassword(PASSWORD);  
  15.     }  
  16. }  
  17. </span>  

然后我们访问这个web服务,从控制台查看日志,可以看到在SOAP信封的Header中包装了<wsse:Security...等元素,元素包括了WS-Security 的一些信息和设置的用户名和密码.如果使用MD5加密,则密码显示为null,只能显示用户名.如果客户端和服务端的用户名或者密码不对应,则登陆不上,会显示"...为通过验证!".

 

数据绑定

 

1.JAXB绑定.JAXB是一套自动映射XML和JAVA 实例的开发接口和工具.如果Web Service发布的接口的参数类型时类,而且返回的类型是List,String等,这样发布的Web Service 与普通的java没区别,因为JAXB都支持.但是JAXB不能将一些java类型自然映射到XML表现形式,例如HashMap,或其他非JavaBean之类,例如接口,Map,这样就要定义一个适配器,使java类型自动适应.一般可以编写一个类继承XmlAdapter,以实现此抽象类的适配器,另外可以安装使用注释XmlJavaTypeAdapter的适配器

 

2.Aegis Databingding.Aegis是一个快速,基于STAX的数据绑定,他能使采用代码优先方式发布Web Service的情况更简单.Aegis支持接口,集合类,MAP和各种数据类型.也不需要注释,也不需要写适配器


(三)HelloWorld

 

准备工作

eclipse 3.6

tomcat 6

jdk 1.7

cxf 相关架包,spring相关架包,jdbc相关架包

 

创建一个工程,把架包添加到lib中

 

 

 

写一个接口

 

Java代码   收藏代码
  1. package com.cxf.test;  
  2.   
  3. import javax.jws.WebParam;  
  4. import javax.jws.WebService;  
  5.   
  6. @WebService  
  7. public interface HelloWorld {  
  8.     String zhuce(String username, String password);  
  9. }  

 写一个实现

 

 

Java代码   收藏代码
  1. package com.cxf.test;  
  2.   
  3. import javax.jws.WebService;  
  4. /** 
  5. * @ WebService:申明为webservice的注解  
  6. *   endpointInterface:要暴露的接口类 
  7. *   serviceName :    服务名 
  8. */  
  9. @WebService(endpointInterface ="com.cxf.test.HelloWorld",  
  10.             serviceName = "HelloWorld")  
  11. public class HelloWorldImpl implements HelloWorld {  
  12.       
  13.     public String zhuce(String username, String password) {  
  14.         String result = "";  
  15.         if(username.equals("admin")){  
  16.             result = "用户名已经存在";  
  17.         }  
  18.         else if (password.length() != 6) {  
  19.             result = "请输入6位数密码";  
  20.         }  
  21.         return result;  
  22.     }  
  23. }  

 发布web service

 

 

Java代码   收藏代码
  1. package com.cxf.test;  
  2.   
  3. import javax.xml.ws.Endpoint;  
  4.   
  5. import org.apache.cxf.jaxws.JaxWsServerFactoryBean;  
  6.   
  7. public class service {  
  8.   
  9.     public static void startService() throws Exception{  
  10.             //通过CXF内置的Jetty应用服务器发布  
  11.             //方法1:用CXF的JaxWsServerFactoryBean类进行发布。(需要CXF相关包)  
  12.             HelloWorldImpl hw = new HelloWorldImpl();  
  13.             JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();  
  14.             factoryBean.setAddress("http://localhost:8080/cxf/HelloWorld");  
  15.             factoryBean.setServiceClass(HelloWorld.class);  
  16.             factoryBean.setServiceBean(hw);  
  17.             factoryBean.create();  
  18.             System.out.println("方法1");  
  19.               
  20.             //方法2:使用Sun JAX-WS 2中Endpoint.publish进行发布  
  21.             /*Endpoint endpoint = Endpoint.publish("http://localhost:10080/cxf/HelloWorld", new HelloWorldImpl()); 
  22.             System.out.println("方法2");*/  
  23.               
  24.     }  
  25.       
  26.     public static void main(String[] args) throws Exception{  
  27.         startService();  
  28.         System.out.println("Web Service 发布成功");  
  29.     }  
  30. }  

 在浏览器里面输入http://localhost:10080/cxf/HelloWorld?wsdl,就可以看见XML文件了,控制台打印 发布成功.



cxf+web service(四)cxf+spring集成


客户端

Java代码   收藏代码
  1. public class Client {  
  2.   
  3.     private Client(){}  
  4.       
  5.     public static void main(String[] args) {  
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-client.xml");  
  7.         HelloWorld hw = (HelloWorld) context.getBean("client");  
  8.         String response = hw.zhuce("piter""123456");  
  9.         System.out.println(response);  
  10.     }  
  11. }  

 客户端配置文件,这里面配置代理工厂,地址,暴露的服务接口.这里也可以直接在客户端代码里面使用JaxWsProxyFactoryBean来发布

Java代码   收藏代码
  1. <import resource="classpath:META-INF/cxf/cxf.xml"/>  
  2.    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>  
  3.    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>  
  4.   
  5.    <bean id="client" class="com.cxf.test.HelloWorld" factory-bean="clientFactory" factory-method="create" />  
  6.   
  7.    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">  
  8.        <property name="serviceClass" value="com.cxf.test.HelloWorld" />  
  9.        <property name="address" value="http://localhost:8080/cxf/ws/HelloWorld" />  
  10.    </bean>  

 然后在spring.xml中加入接口的配置

Java代码   收藏代码
  1. <!-- Import Apache CXF Bean Definition -->  
  2.     <import resource="classpath:META-INF/cxf/cxf.xml"/>  
  3.     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>  
  4.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>  
  5.   
  6.     <jaxws:endpoint id="helloWorld"   
  7.         implementor="com.cxf.test.HelloWorldImpl"   
  8.         address="/HelloWorld"/>  

 OK,最后在浏览器输入http://localhost:8080/cxf/ws,如下图,发布成功!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值