CXF的拦截器是CXF功能最主要的扩展点。通过自定义的Interceptor,可以改变请求和响应的一些消息处理,其中最基本的原理还是一个动态代理。
applicationContext.xml 配置
Interceptor是CXF架构中一个很有特色的模式。你可以在不对核心模块进行修改的情况下,动态添加很多功能。这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理。
CXF拦截器使用如下
1:服务端增加自定义拦截器
- package com.lzw.springcxf.auth;
- 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;
- /**
- * @Description: 自定义拦截器在哪个阶段实施拦截
- * @author lzw
- * @date 2013年11月6日 上午11:54:48
- * @version V1.0
- * @Copyright (c)
- */
- public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
- public AuthInterceptor() {
- //拦截器在调用方法之前拦截SOAP消息
- super(Phase.PRE_INVOKE);
- }
- /**
- * @Description: 拦截器操作
- * @param msg 被拦截到的SOAP消息
- * @throws Fault
- */
- @Override
- public void handleMessage(SoapMessage msg) throws Fault {
- System.out.println("=====自定义拦截器=======");
- //获取SOAP消息的Header
- List<Header> headers = msg.getHeaders();
- //如果没有Header
- if(headers == null || headers.size() < 1) {
- throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"));
- }
- //获取Header携带是用户和密码信息
- Header firstHeader = headers.get(0);
- Element ele = (Element) firstHeader.getObject();
- NodeList userIdEle = ele.getElementsByTagName("userId");
- NodeList userPassEle = ele.getElementsByTagName("userPass");
- if (userIdEle.getLength() != 1) {
- throw new Fault(new IllegalArgumentException("用户Id格式不对"));
- }
- if (userPassEle.getLength() != 1) {
- throw new Fault(new IllegalArgumentException("用户密码格式不对"));
- }
- //获取元素的文本内容
- String userId = userIdEle.item(0).getTextContent();
- String userPass = userPassEle.item(0).getTextContent();
- if (!userId.equals("lzw") || !userPass.equals("123456")) {
- throw new Fault(new IllegalArgumentException("用户和密码不正确"));
- }
- }
- }
- <jaxws:endpoint
- implementor="#handleService"
- address="/cxf">
- <!-- 配置IN拦截器 -->
- <jaxws:inInterceptors>
- <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
- <bean class="com.lzw.springcxf.auth.AuthInterceptor"></bean>
- </jaxws:inInterceptors>
- <!-- 配置OUT拦截器 -->
- <jaxws:outInterceptors>
- <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
- </jaxws:outInterceptors>
- </jaxws:endpoint>
客户端代码:
定义客户端拦截器
- package com.lzw.springcxf.client;
- 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 AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
- private String userId;
- private String userPass;
- public AddHeaderInterceptor(String userId, String userPass) {
- super(Phase.PREPARE_SEND);
- this.userId = userId;
- this.userPass = userPass;
- }
- @Override
- public void handleMessage(SoapMessage msg) throws Fault {
- List<Header> headers = msg.getHeaders();
- //创建Document对象
- Document doc = DOMUtils.createDocument();
- Element ele = doc.createElement("authHeader");
- //配置服务器端Head信息的用户密码
- Element eleId= doc.createElement("userId");
- eleId.setTextContent(userId);
- Element elePass = doc.createElement("userPass");
- elePass.setTextContent(userPass);
- ele.appendChild(eleId);
- ele.appendChild(elePass);
- /**
- * 生成的XML文档
- * <authHeader>
- * <userId>lzw</userId>
- * <userPass>123456</userPass>
- * </authHeader>
- */
- headers.add(new Header(new QName(""), ele));
- }
- }
客户端调用:
- package com.lzw.springcxf.client;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.List;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.frontend.ClientProxy;
- import org.apache.cxf.interceptor.LoggingInInterceptor;
- import org.apache.cxf.interceptor.LoggingOutInterceptor;
- import com.lzw.springcxf.service.ClubModel;
- import com.lzw.springcxf.service.Entry;
- import com.lzw.springcxf.service.HandleService;
- import com.lzw.springcxf.service.PlayerModel;
- import com.lzw.springcxf.service.StringPlayer;
- import com.lzw.springcxf.service.impl.HandleServiceTest;
- public class WSClient {
- public static void main(String[] args) throws IOException {
- HandleServiceTest factory = new HandleServiceTest();
- HandleService handleService = factory.getHandleServiceImplPort();
- Client client = ClientProxy.getClient(handleService);
- client.getOutInterceptors().add(new AddHeaderInterceptor("lzw", "123456"));
- client.getOutInterceptors().add(new LoggingOutInterceptor(new PrintWriter(new FileWriter("in.txt"))));
- client.getInInterceptors().add(new LoggingInInterceptor(new PrintWriter(new FileWriter("out.txt"))));
- System.out.println(handleService.sayName("内马尔"));
- ClubModel clubModel = new ClubModel();
- clubModel.setClubId(1111);
- clubModel.setClubName("巴塞罗那");
- clubModel.setCountry("西班牙");
- System.out.println("============================");
- List<PlayerModel> players = handleService.getPlayerByClub(clubModel);
- for (PlayerModel play:players) {
- System.out.println(play.getPlayerName());
- }
- System.out.println("============================");
- StringPlayer allPlayer = handleService.getAllPlayers();
- for (Entry entry:allPlayer.getEntries()) {
- System.out.println(entry.getKey() + entry.getValue().getPlayerName());
- }
- }
- }
至此服务端打印信息
- ID: 5
- Address: http://localhost:8080/Spring-Cxf-Demo/lzw/cxf
- Encoding: UTF-8
- Http-Method: POST
- Content-Type: text/xml; charset=UTF-8
- Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[274], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.6]}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Header><authHeader>
- <userId>lzw</userId><userPass>123456</userPass>
- </authHeader></soap:Header><soap:Body>
- <ns2:getAllPlayers xmlns:ns2="http://service.springcxf.lzw.com/"/></soap:Body></soap:Envelope>
- --------------------------------------
- =====自定义拦截器=======
- 2013-11-6 14:50:51 org.apache.cxf.services.handleServiceTest.HandleServiceImplPort.HandleService
- 信息: Outbound Message
- ---------------------------
- ID: 5
- Encoding: UTF-8
- Content-Type: text/xml
- Headers: {}
- Payload:
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Body><ns2:getAllPlayersResponse xmlns:ns2="http://service.springcxf.lzw.com/">
- <return><entries><key>第4位球员是:</key><value><playerId>4</playerId><playerName>贝尔</playerName>
- <playerNumber>11</playerNumber><playerPosition>中场</playerPosition></value></entries><entries>
- <key>第3位球员是:</key><value><playerId>3</playerId><playerName>C罗</playerName>
- <playerNumber>7</playerNumber><playerPosition>前锋</playerPosition></value>
- </entries><entries><key>第1位球员是:</key><value><playerId>1</playerId>
- <playerName>梅西</playerName><playerNumber>10</playerNumber><playerPosition>前锋</playerPosition>
- </value></entries><entries><key>第2位球员是:</key><value><playerId>2</playerId><playerName>内马尔</playerName>
- <playerNumber>11</playerNumber><playerPosition>前锋</playerPosition></value></entries></return>
- </ns2:getAllPlayersResponse></soap:Body></soap:Envelope>
- --------------------------------------
结束: