cxf+web service(二)代理工厂,安全验证,数据绑定
(二)代理工厂,安全验证,数据绑定
代理工厂
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输入拦截器
<bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <map> <entry key="xx" value="xx"/> </map> </bean>
在接口服务里面加入关系
<jaxws:inInterceptors> <ref bean="wss4jInInterceptor" /> </jaxws:inInterceptors>
下面是服务器端具体密码回调处理类,它负责接收并处理客户端提交的用户名和密码,这个方法没有返回值,显示,如果验证失败,抛出异常表示.
import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSConstants; import org.apache.ws.security.WSPasswordCallback; import org.apache.ws.security.WSSecurityException; public class ServerPasswordCallbackHandler implements CallbackHandler { public final static String USER = "liu"; public final static String PASSWORD = "lius";//设置用户名密码 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback wspassCallback = (WSPasswordCallback) callbacks[0]; System.out.println(wspassCallback.getIdentifier() + "\t" + wspassCallback.getPassword()); if(WSConstants.PASSWORD_TEXT.equals(wspassCallback.getPasswordType())){ if (wspassCallback.getIdentifier().equals(USER) && wspassCallback.getPassword().equals(PASSWORD)) { System.out.println(".................验证通过!"); System.out.println(".................identifier = " + USER); System.out.println(".................password = " + PASSWORD); } else { throw new WSSecurityException("............未通过验证!"); } } else { //密码使用MD5密文发送 System.out.println(wspassCallback.getIdentifier()); wspassCallback.setPassword(PASSWORD); } } }
2.客户端实现:在spring.xml中配置WSS4J输出拦截器
<bean id="wss4jOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <map> <entry key="xx" value="xx"/> </map> </bean>
在服务接口里加入关系
<jaxws:outInterceptors> <ref bean="wss4jOutInterceptor" /> </jaxws:outInterceptors
这里使用了WSS4J输出拦截器,因为要将用户名和密码输出到服务器进行验证处理.另外与服务端不同的是多了一个user参数初始化WSS4J的输出拦截器,用于初始化用户名,这是一个必选,稍后将在下面的客户端密码回调处理类进行重新设定值
import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ClientPasswordCallbackHandler implements CallbackHandler{ public final static String USER = "liu"; public final static String PASSWORD = "lius";//设置用户名密码 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback wspassCallback = (WSPasswordCallback)callbacks[0]; wspassCallback.setIdentifier(USER); wspassCallback.setPassword(PASSWORD); } }
然后我们访问这个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和各种数据类型.也不需要注释,也不需要写适配器
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐