WebService学习笔记(七)自定义拦截器

来源:互联网 发布:如何生成数据透视表 编辑:程序博客网 时间:2024/06/08 06:12

添加自定义拦截器,CXF允许程序员自己操作SOAP协议。

Envelope可分为两部分,Header(可选) 与Body,通过自定义拦截器,可在Header部分里添加认证信息。


服务端代码:


需要实现PhaseInterceptor,但一般继承抽象类AbstractPhaseInterceptor就可以了。

package com.skymr.hello.ws.interceptor;import java.util.List;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.headers.Header;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.w3c.dom.Element;import org.w3c.dom.NodeList;public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{public AuthInterceptor() {//调用之前认证super(Phase.PRE_INVOKE);}/** * 取出Header头进行认证 */public void handleMessage(SoapMessage msg) throws Fault {List<Header> headers = msg.getHeaders();if(headers == null || headers.size()==0){throw new Fault(new IllegalArgumentException("找不到认证信息"));}Header header = headers.get(0);Element auth = (Element)header.getObject();NodeList uNl = auth.getElementsByTagName("username");NodeList uPw = auth.getElementsByTagName("password");if(uNl.getLength() < 1){throw new Fault(new IllegalArgumentException("找不到用户名信息"));}if(uPw.getLength() < 1){throw new Fault(new IllegalArgumentException("找不到密码信息"));}String userName = uNl.item(0).getTextContent();String password = uPw.item(0).getTextContent();if("admin".equals(userName) && "admin".equals(password)){System.out.println("认证成功");}else{throw new Fault(new IllegalArgumentException("认证失败"));}}}

客户端代码

package com.skymr.hello.ws.interceptor;import java.util.List;import javax.xml.namespace.QName;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.headers.Header;import org.apache.cxf.helpers.DOMUtils;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.w3c.dom.Document;import org.w3c.dom.Element;public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{protected String userName;protected String password;public AuthInterceptor(String userName, String password) {//发送前拦截super(Phase.PREPARE_SEND);this.userName = userName;this.password = password;}/** * 生成认证信息 * <head> * <authrity> * <username></username> * <password></password> * </authrity> * </head> */public void handleMessage(SoapMessage msg) throws Fault {System.out.println("--------------");List<Header> headers = msg.getHeaders();Document doc = DOMUtils.createDocument();Element auth = doc.createElement("authrity");Element userNameNode = doc.createElement("username");Element passwordNode = doc.createElement("password");userNameNode.setTextContent(userName);passwordNode.setTextContent(password);auth.appendChild(userNameNode);auth.appendChild(passwordNode);//QName的参数随便取个名字headers.add(0,new Header(new QName("head"), auth));}}

服务端和客户端添加各自拦截器后进行测试:

服务端添加:是在spring与CXF整合的基础上

    <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />      <jaxws:endpoint id="userOp" implementor="#userOperator" address="/UserOperator" ></jaxws:endpoint>        <bean id="logInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>    <!-- 自定义拦截器,认证拦截 -->    <bean id="authInterceptor" class="com.skymr.hello.ws.interceptor.AuthInterceptor"></bean>    <cxf:bus>    <cxf:inInterceptors>    <ref bean="logInterceptor"/>    <ref bean="authInterceptor"/>    </cxf:inInterceptors>    </cxf:bus>

客户端添加:

HelloWorldws factory = new HelloWorldws();HelloWorld hw = factory.getHelloWorldBeanPort();Client client = ClientProxy.getClient(hw);client.getOutInterceptors().add(new AuthInterceptor("admin","admin"));client.getOutInterceptors().add(new LoggingOutInterceptor());System.out.println(hw.sayHello("skymr"));

控制台输出:

九月 15, 2015 11:21:07 上午 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDLINFO: Creating Service {http://impl.ws.hello.skymr.com/}helloWorldws from WSDL: http://192.168.2.102:8080/spring_cxf/doWS/HelloWorld?wsdl--------------九月 15, 2015 11:21:09 上午 org.apache.cxf.services.helloWorldws.HelloWorldBeanPort.HelloWorldINFO: Outbound Message---------------------------ID: 1Address: http://192.168.2.102:8080/spring_cxf/doWS/HelloWorldEncoding: UTF-8Http-Method: POSTContent-Type: text/xmlHeaders: {Accept=[*/*], SOAPAction=[""]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><authrity><username>admin</username><password>admin</password></authrity></soap:Header><soap:Body><ns2:sayHello xmlns:ns2="http://ws.hello.skymr.com/"><arg0>skymr</arg0></ns2:sayHello></soap:Body></soap:Envelope>--------------------------------------你好skymr,欢迎进入Web Service学习课程

取出SOAP消息:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><authrity><username>admin</username><password>admin</password></authrity></soap:Header><soap:Body>...</soap:Body></soap:Envelope>

自定义拦截器完成。

0 0