CXF实战之自定义拦截器(五)

来源:互联网 发布:修复痘印的方法知乎 编辑:程序博客网 时间:2024/06/06 08:38

CXF已经内置了一些拦截器,这些拦截器大部分默认添加到拦截器链中,有些拦截器也可以手动添加,如手动添加CXF提供的日志拦截器。也可以自定义拦截器,CXF中实现自定义拦截器很简单,只要继承AbstractPhaseInterceptor或者AbstractPhaseInterceptor的子类(如AbstractSoapInterceptor)即可。

自定义权限认证拦截器

权限认证拦截器处理SOAPHeader中的认证信息,客户端在发起请求时在SOAPHeader中添加认证信息,服务端在接收到请求后,校验认证信息,校验通过则继续执行,校验不通过则返回错误。

<!-- 认证信息格式如下 --><auth xmlns="http://www.tmp.com/auth">      <name>admin</name>      <password>admin</password>  </auth>

客户端添加授权拦截器

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;/** * 添加授权拦截器 * 用于在客户端发请求时添加授权 * @author accountwcx@qq.com * */public class AuthAddInterceptor extends AbstractPhaseInterceptor<SoapMessage> {    public AuthAddInterceptor(){        //准备发送阶段        super(Phase.PREPARE_SEND);    }    @Override    public void handleMessage(SoapMessage message) throws Fault {        List<Header> headers = message.getHeaders();        Document doc = DOMUtils.createDocument();        //Element auth = doc.createElement("auth");        Element auth = doc.createElementNS("http://www.tmp.com/auth", "auth");        Element name = doc.createElement("name");        name.setTextContent("admin");        Element password = doc.createElement("password");          password.setTextContent("admin");          auth.appendChild(name);          auth.appendChild(password);        headers.add(new Header(new QName(""), auth));    }}

服务端授权验证拦截器

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.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.w3c.dom.Element;import org.w3c.dom.NodeList;/** * 服务端输入拦截器 * 拦截请求有没有授权信息 * @author accountwcx@qq.com * */public class AuthValidateInterceptor extends AbstractPhaseInterceptor<SoapMessage> {    public AuthValidateInterceptor(){        super(Phase.PRE_INVOKE);    }    @Override    public void handleMessage(SoapMessage message) throws Fault {        List<Header> headers = message.getHeaders();        if(headers == null || headers.size() < 1) {              throw new Fault(new Exception("无授权信息!"));        }        Element auth = null;        //获取授权信息元素        for(Header header : headers){            QName qname = header.getName();            String ns = qname.getNamespaceURI();            String tagName = qname.getLocalPart();            if(ns != null && ns.equals("http://www.tmp.com/auth") && tagName != null && tagName.equals("auth")){                auth = (Element)header.getObject();                break;            }        }        //如果授权信息元素不存在,提示错误        if(auth == null){            throw new Fault(new Exception("无授权信息!"));        }        NodeList nameList = auth.getElementsByTagName("name");        NodeList pwdList = auth.getElementsByTagName("password");        if(nameList.getLength() != 1 || pwdList.getLength() != 1){            throw new Fault(new Exception("授权信息错误!"));        }        String name = nameList.item(0).getTextContent();        String password = pwdList.item(0).getTextContent();        if(!"admin".equals(name) || !"admin".equals(password)){            throw new Fault(new Exception("授权信息错误!"));        }    }}

服务端拦截器配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:jaxws="http://cxf.apache.org/jaxws"    xmlns:soap="http://cxf.apache.org/bindings/soap"    xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd         http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd         http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">    <jaxws:endpoint id="helloWSEndpoint" implementor="#helloWS" address="/hello">        <jaxws:inInterceptors>            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>            <bean class="com.rvho.cxfserver.interceptor.AuthValidateInterceptor"></bean>        </jaxws:inInterceptors>        <jaxws:outInterceptors>            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>        </jaxws:outInterceptors>    </jaxws:endpoint></beans>

客户端请求

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();factory.setServiceClass(HelloWS.class);factory.setAddress("http://localhost:8280/cxfserver/services/hello");factory.getInInterceptors().add(new org.apache.cxf.interceptor.LoggingInInterceptor());//客户端授权拦截器factory.getOutInterceptors().add(new com.rvho.cxfclient.interceptor.AuthAddInterceptor());factory.getOutInterceptors().add(new org.apache.cxf.interceptor.LoggingOutInterceptor());HelloWS helloWS = factory.create(HelloWS.class);String welcome = helloWS.welcome("accountwcx@qq.com");

CXF日志拦截器

CXF提供了输入日志拦截器LoggingInInterceptor和输出日志拦截器LoggingOutInterceptor,日志拦截器可以用在服务端也可以用在客户端。在测试或者调试的时候,可以用日志拦截器输出服务端、客户端请求和接收到的信息。

服务端日志内容

七月 30, 2015 10:51:37 上午 org.apache.cxf.services.HelloWSService.HelloWSPort.HelloWS信息: Inbound Message----------------------------ID: 1Address: http://localhost:8280/cxfserver/services/helloEncoding: UTF-8Http-Method: POSTContent-Type: text/xml; charset=UTF-8Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[212], content-type=[text/xml; charset=UTF-8], host=[localhost:8280], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 3.1.1]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:welcome xmlns:ns2="http://www.tmp.com/services/hello"><name>accountwcx@qq.com</name></ns2:welcome></soap:Body></soap:Envelope>--------------------------------------七月 30, 2015 10:51:37 上午 org.apache.cxf.services.HelloWSService.HelloWSPort.HelloWS信息: Outbound Message---------------------------ID: 1Response-Code: 200Encoding: UTF-8Content-Type: text/xmlHeaders: {}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:welcomeResponse xmlns:ns2="http://www.tmp.com/services/hello"><return>欢迎使用CXF!accountwcx@qq.com</return></ns2:welcomeResponse></soap:Body></soap:Envelope>--------------------------------------

客户端日志内容

七月 30, 2015 10:51:37 上午 org.apache.cxf.services.HelloWSService.HelloWSPort.HelloWS信息: Outbound Message---------------------------ID: 1Address: http://localhost:8280/cxfserver/services/helloEncoding: UTF-8Http-Method: POSTContent-Type: text/xmlHeaders: {Accept=[*/*], SOAPAction=[""]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:welcome xmlns:ns2="http://www.tmp.com/services/hello"><name>accountwcx@qq.com</name></ns2:welcome></soap:Body></soap:Envelope>--------------------------------------七月 30, 2015 10:51:37 上午 org.apache.cxf.services.HelloWSService.HelloWSPort.HelloWS信息: Inbound Message----------------------------ID: 1Response-Code: 200Encoding: UTF-8Content-Type: text/xml;charset=UTF-8Headers: {content-type=[text/xml;charset=UTF-8], Date=[Thu, 30 Jul 2015 02:51:37 GMT], Server=[Apache-Coyote/1.1], transfer-encoding=[chunked]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:welcomeResponse xmlns:ns2="http://www.tmp.com/services/hello"><return>欢迎使用CXF!accountwcx@qq.com</return></ns2:welcomeResponse></soap:Body></soap:Envelope>--------------------------------------欢迎使用CXF!accountwcx@qq.com
2 0
原创粉丝点击