Interceptor是CXF架构中一个很有特色的模式。你可以在不对核心模块进行修改的情况下,动态添加很多功能。这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处。简单的说,可以在收到请求后,还未进行业务处理前,进行处理。或者在请求包发送前,进行报文的处理。

Interceptor

定义两个方法,一个处理消息 handleMessage, 一个是处理错误 handleFault。

InterceptorChain

单个的Interceptor功能有限,CXF要实现一个SOAP消息处理,需要将许许多多的Interceptor组合在一起使用。因此设计了 InterceptorChain,在我看了InterceptorChain就像是一个Interceptor的小队长。 小队长有调配安置Interceptor的权力(add,remove),也有控制消息处理的权力(doInterceptor,pause,resume,reset,abort),同时也有交付错误处理的权力( {get|set}FaultObserver)。更有意思的是为灵活控制Interceptor的处理消息顺序(doInterceptStartingAt,doInterceptorStartingAfter),这也是InterceptorChain比较难理解的地方。

Fault

定义了CXF中的错误消息。

InterceptorProvider

  这里定义了Interceptor的后备保障部队。我们可以在InterceptorProvider中设置In,Out,InFault,OutFault 后备小分队,添加我们所希望添加的Interceptor。而InterceptorChain会根据这些后备小分队,组建自己的小分队实例,完成具体的作战功能任务。

AbstractAttributedInterceptorProvider

InterceptorProvider实现的抽象类,由于这个类来继承了HashMap,我们可以像这个类中存储一些属性信息。

AbrstractBasicInterceptorProvider

与AbstractAttributedInterceptorProvider不同,这个Interceptor只是简单实现了InterceptorProvider的功能,并不提供对其属性存储的扩展。

Message

由于Interceptor是针对Message来进行处理的,当你打开Message这个类文件时,你会发现在Message中定义了很多常量,同时你还可以从Message中获取到很多与Message操作相关的信息。可以获取设置的对象有InterceptorChain Exchange Destination,还有获取设置Content的泛型接口,是不是感觉Message和Bus差不多,都成了大杂货铺,一切与消息处理相关的信息都可以放在Message中。

服务端拦截器

  1. package hs.cxf.soapHeader;
  2.  
  3. import javax.xml.soap.SOAPException;
  4.  
  5. import javax.xml.soap.SOAPHeader;
  6.  
  7. import javax.xml.soap.SOAPMessage;
  8.  
  9. import org.apache.cxf.binding.soap.SoapMessage;
  10.  
  11. import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
  12.  
  13. import org.apache.cxf.interceptor.Fault;
  14.  
  15. import org.apache.cxf.phase.AbstractPhaseInterceptor;
  16.  
  17. import org.apache.cxf.phase.Phase;
  18.  
  19. import org.w3c.dom.NodeList;
  20.  
  21. /**
  22.  
  23. *
  24.  
  25. * @Title:获取soap头信息
  26.  
  27. *
  28.  
  29. * @Description:
  30.  
  31. *
  32.  
  33. * @Copyright:
  34.  
  35. *
  36.  
  37. * @author zz
  38.  
  39. * @version 1.00.000
  40.  
  41. *
  42.  
  43. */
  44.  
  45. public class ReadSoapHeader extends AbstractPhaseInterceptor<SoapMessage> {
  46.  
  47. private SAAJInInterceptor saa = new SAAJInInterceptor();
  48.  
  49. public ReadSoapHeader() {
  50.  
  51. super(Phase.PRE_PROTOCOL);
  52.  
  53. getAfter().add(SAAJInInterceptor.class.getName());
  54.  
  55. }
  56.  
  57. public void handleMessage(SoapMessage message) throws Fault {
  58.  
  59. SOAPMessage mess = message.getContent(SOAPMessage.class);
  60.  
  61. if (mess == null) {
  62.  
  63. saa.handleMessage(message);
  64.  
  65. mess = message.getContent(SOAPMessage.class);
  66.  
  67. }
  68.  
  69. SOAPHeader head = null;
  70.  
  71. try {
  72.  
  73. head = mess.getSOAPHeader();
  74.  
  75. } catch (SOAPException e) {
  76.  
  77. e.printStackTrace();
  78.  
  79. }
  80.  
  81. if (head == null) {
  82.  
  83. return;
  84.  
  85. }
  86.  
  87. try {
  88.  
  89. //读取自定义的节点
  90.  
  91. NodeList nodes = head.getElementsByTagName("tns:spId");
  92.  
  93. NodeList nodepass = head.getElementsByTagName("tns:spPassword");
  94.  
  95. //获取节点值,简单认证
  96.  
  97. if (nodes.item(0).getTextContent().equals("wdw")) {
  98.  
  99. if (nodepass.item(0).getTextContent().equals("wdwsb")) {
  100.  
  101. System.out.println("认证成功");
  102.  
  103. }
  104.  
  105. } else {
  106.  
  107. SOAPException soapExc = new SOAPException("认证错误");
  108.  
  109. throw new Fault(soapExc);
  110.  
  111. }
  112.  
  113. } catch (Exception e) {
  114.  
  115. SOAPException soapExc = new SOAPException("认证错误");
  116.  
  117. throw new Fault(soapExc);
  118.  
  119. }
  120.  
  121. }
  122.  
  123. }

配置文件中新增拦截器配置

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2.  
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  
  5. xmlns:jaxws="http://cxf.apache.org/jaxws"
  6.  
  7. xsi:schemaLocation="
  8.  
  9. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  10.  
  11. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
  12.  
  13. <import resource="classpath:META-INF/cxf/cxf.xml" />
  14.  
  15. <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
  16.  
  17. <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
  18.  
  19. <bean id="jaxWsServiceFactoryBean"
  20.  
  21. class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
  22.  
  23. <property name="wrapped" value="true" />
  24.  
  25. <property name="dataBinding" ref="aegisBean" />
  26.  
  27. </bean>
  28.  
  29. <bean id="aegisBean"
  30.  
  31. class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
  32.  
  33. <jaxws:endpoint id="CollectiveServices"
  34.  
  35. implementor="hs.cxf.server.WebServiceSampleImpl" address="/HelloWorld">
  36.  
  37. <jaxws:inInterceptors>
  38.  
  39. <!-- 日志拦截器 -->
  40.  
  41. <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
  42.  
  43. <!-- 自定义拦截器 -->
  44.  
  45. <bean class="hs.cxf.soapHeader.ReadSoapHeader"/>
  46.  
  47. </jaxws:inInterceptors>
  48.  
  49. <jaxws:serviceFactory>
  50.  
  51. <ref bean="jaxWsServiceFactoryBean"/>
  52.  
  53. </jaxws:serviceFactory>
  54.  
  55. </jaxws:endpoint>
  56.  
  57. </beans>

客户端拦截器:

  1. package hs.cxf.client.SoapHeader;
  2.  
  3. import java.util.List;
  4.  
  5. import javax.xml.namespace.QName;
  6.  
  7. import org.apache.cxf.binding.soap.SoapHeader;
  8.  
  9. import org.apache.cxf.binding.soap.SoapMessage;
  10.  
  11. import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
  12.  
  13. import org.apache.cxf.headers.Header;
  14.  
  15. import org.apache.cxf.helpers.DOMUtils;
  16.  
  17. import org.apache.cxf.interceptor.Fault;
  18.  
  19. import org.apache.cxf.phase.Phase;
  20.  
  21. import org.w3c.dom.Document;
  22.  
  23. import org.w3c.dom.Element;
  24.  
  25. /**
  26.  
  27. *
  28.  
  29. * @Title:在发送消息前,封装Soap Header 信息
  30.  
  31. *
  32.  
  33. * @Description:
  34.  
  35. *
  36.  
  37. * @Copyright:
  38.  
  39. *
  40.  
  41. * @author zz
  42.  
  43. * @version 1.00.000
  44.  
  45. *
  46.  
  47. */
  48.  
  49. public class AddSoapHeader extends AbstractSoapInterceptor {
  50.  
  51. private static String nameURI="http://127.0.0.1:8080/cxfTest/ws/HelloWorld";
  52.  
  53. public AddSoapHeader(){
  54.  
  55. super(Phase.WRITE);
  56.  
  57. }
  58.  
  59. public void handleMessage(SoapMessage message) throws Fault {
  60.  
  61. String spPassword="wdwsb";
  62.  
  63. String spName="wdw";
  64.  
  65. QName qname=new QName("RequestSOAPHeader");
  66.  
  67. Document doc=DOMUtils.createDocument();
  68.  
  69. //自定义节点
  70.  
  71. Element spId=doc.createElement("tns:spId");
  72.  
  73. spId.setTextContent(spName);
  74.  
  75. //自定义节点
  76.  
  77. Element spPass=doc.createElement("tns:spPassword");
  78.  
  79. spPass.setTextContent(spPassword);
  80.  
  81. Element root=doc.createElementNS(nameURI, "tns:RequestSOAPHeader");
  82.  
  83. root.appendChild(spId);
  84.  
  85. root.appendChild(spPass);
  86.  
  87. SoapHeader head=new SoapHeader(qname,root);
  88.  
  89. List<Header> headers=message.getHeaders();
  90.  
  91. headers.add(head);
  92.  
  93. System.out.println(">>>>>添加header<<<<<<<");
  94.  
  95. }
  96.  
  97. }

客户端调用时:

  1. package hs.cxf.client;
  2.  
  3. import hs.cxf.client.SoapHeader.AddSoapHeader;
  4.  
  5. import java.util.ArrayList;
  6.  
  7. import javax.xml.bind.JAXBElement;
  8.  
  9. import javax.xml.namespace.QName;
  10.  
  11. import org.apache.cxf.endpoint.Client;
  12.  
  13. import org.apache.cxf.frontend.ClientProxy;
  14.  
  15. import org.apache.cxf.interceptor.Interceptor;
  16.  
  17. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
  18.  
  19. import org.apache.cxf.transport.http.HTTPConduit;
  20.  
  21. import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
  22.  
  23. /**
  24.  
  25. * @Title:
  26.  
  27. *
  28.  
  29. * @Description:
  30.  
  31. *
  32.  
  33. * @Copyright:
  34.  
  35. *
  36.  
  37. * @author zz
  38.  
  39. * @version 1.00.000
  40.  
  41. *
  42.  
  43. */
  44.  
  45. public class TestClient {
  46.  
  47. /**
  48.  
  49. * 测试1
  50.  
  51. */
  52.  
  53. @SuppressWarnings("unchecked")
  54.  
  55. public void testSend1() {
  56.  
  57. try {
  58.  
  59. JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
  60.  
  61. ArrayList<Interceptor> list = new ArrayList<Interceptor>();
  62.  
  63. // 添加soap header
  64.  
  65. list.add(new AddSoapHeader());
  66.  
  67. // 添加soap消息日志打印
  68.  
  69. list.add(new org.apache.cxf.interceptor.LoggingOutInterceptor());
  70.  
  71. factory.setOutInterceptors(list);
  72.  
  73. factory.setServiceClass(WebServiceSample.class);
  74.  
  75. factory.setAddress("http://127.0.0.1:8080/cxfTest/ws/HelloWorld");
  76.  
  77. Object obj = factory.create();
  78.  
  79. System.out.println(obj == null ? "NULL" : obj.getClass().getName());
  80.  
  81. if (obj != null) {
  82.  
  83. WebServiceSample ws = (WebServiceSample) obj;
  84.  
  85. String str = ws.say("test");
  86.  
  87. System.out.println(str);
  88.  
  89. str = ws.say("1111");
  90.  
  91. System.out.println(str);
  92.  
  93. User u = new User();
  94.  
  95. JAXBElement<String> je = new JAXBElement<String>(new QName(
  96.  
  97. "http://bean.cxf.hs", "name"), String.class, "张三");
  98.  
  99. u.setName(je);
  100.  
  101. str = ws.sayUserName(u);
  102.  
  103. System.out.println(str);
  104.  
  105. // 通过对象来交互
  106.  
  107. ReqBean req = new ReqBean();
  108.  
  109. req.setExp(new JAXBElement<String>(new QName(
  110.  
  111. "http://bean.cxf.hs", "exp"), String.class,
  112.  
  113. "<exp>111<exp>"));
  114.  
  115. req.setSeqId(new JAXBElement<String>(new QName(
  116.  
  117. "http://bean.cxf.hs", "seqId"), String.class,
  118.  
  119. "12345678"));
  120.  
  121. RespBean resp = ws.action(req);
  122.  
  123. System.out.println("resp_id:" + resp.getRespId().getValue());
  124.  
  125. System.out.println("resp_exp:" + resp.getExp().getValue());
  126.  
  127. }
  128.  
  129. } catch (Exception ex) {
  130.  
  131. ex.printStackTrace();
  132.  
  133. }
  134.  
  135. }
  136.  
  137. /**
  138.  
  139. * 测试2
  140.  
  141. */
  142.  
  143. @SuppressWarnings("unchecked")
  144.  
  145. public void testSend2() {
  146.  
  147. String webServiceUrl = "http://127.0.0.1:8080/cxfTest/ws/HelloWorld";
  148.  
  149. String webServiceConTimeout = "60000";
  150.  
  151. String webServiceRevTimeout = "60000";
  152.  
  153. JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
  154.  
  155. ArrayList<Interceptor> list = new ArrayList<Interceptor>();
  156.  
  157. // 添加soap header 信息
  158.  
  159. list.add(new AddSoapHeader());
  160.  
  161. // 添加soap消息日志打印
  162.  
  163. list.add(new org.apache.cxf.interceptor.LoggingOutInterceptor());
  164.  
  165. factory.setOutInterceptors(list);
  166.  
  167. factory.setServiceClass(WebServiceSample.class);
  168.  
  169. factory.setAddress(webServiceUrl);
  170.  
  171. WebServiceSample service = (WebServiceSample) factory.create();
  172.  
  173. //超时时间设置
  174.  
  175. Client clientP = ClientProxy.getClient(service);
  176.  
  177. HTTPConduit http = (HTTPConduit) clientP.getConduit();
  178.  
  179. HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
  180.  
  181. httpClientPolicy.setConnectionTimeout(Integer
  182.  
  183. .valueOf(webServiceConTimeout));
  184.  
  185. httpClientPolicy.setReceiveTimeout(Integer
  186.  
  187. .valueOf(webServiceRevTimeout));
  188.  
  189. httpClientPolicy.setAllowChunking(false);
  190.  
  191. http.setClient(httpClientPolicy);
  192.  
  193. // 通过对象来交互
  194.  
  195. ReqBean req = new ReqBean();
  196.  
  197. req.setExp(new JAXBElement<String>(new QName(
  198.  
  199. "http://bean.cxf.hs", "exp"), String.class,
  200.  
  201. "<exp>111<exp>"));
  202.  
  203. req.setSeqId(new JAXBElement<String>(new QName(
  204.  
  205. "http://bean.cxf.hs", "seqId"), String.class,
  206.  
  207. "12345678"));
  208.  
  209. System.out.println(">>>>>>发送消息<<<<<<<<<");
  210.  
  211. RespBean resp = service.action(req);
  212.  
  213. System.out.println("resp_id:" + resp.getRespId().getValue());
  214.  
  215. System.out.println("resp_exp:" + resp.getExp().getValue());
  216.  
  217. }
  218.  
  219. /**
  220.  
  221. * @param args
  222.  
  223. */
  224.  
  225. public static void main(String[] args) {
  226.  
  227. TestClient tc = new TestClient();
  228.  
  229. tc.testSend1();
  230.  
  231. System.out.println(">>>>>>>>>>>>2<<<<<<<<<<<<<");
  232.  
  233. tc.testSend2();
  234.  
  235. System.out.println(">>>>>>>>>>>>END<<<<<<<<<<<<<");
  236.  
  237. }
  238.  
  239. }

CXF 中自定义SOAPHeader的更多相关文章

  1. Html中自定义鼠标的形状

    Html中自定义鼠标的形状 <html> <head> <title>自定义的鼠标形状</title> <meta http-equiv=&quo ...

  2. 教你一招:在PowerPoint中自定义可输入文本的占位符

    日常生活中,当我们设计多媒体课件时,默认的版式其实已经够用了.但是,很多时候,我们需要更加个性一点,所以,我们需要自定义很多东西.本文介绍在PowerPoint中自定义可输入文本的占位符. 一.占位符 ...

  3. android代码优化----ListView中自定义adapter的封装(ListView的模板写法)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  4. 在Eclipse中自定义类似syso的快捷代码模板

    sysout/syso syserr/ syse 点击菜单栏的“Window”->“Preferences”,打开“Preferences”对话框.在Preferences”对话框中点击“Jav ...

  5. 在.net桌面程序中自定义鼠标光标

    有的时候,一个自定义的鼠标光标能给你的程序增色不少.本文这里介绍一下如何在.net桌面程序中自定义鼠标光标.由于.net的桌面程序分为WinForm和WPF两种,这里分别介绍一下. WinForm程序 ...

  6. .net中自定义过滤器对Response内容进行处理

    原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 代码DEMO:http://files.cnblogs.com/ ...

  7. 在cxf中使用配置避免增加字段导致客户端必须更新、同步实体属性的问题

    在使用cxf实现webservice时,经常碰到的问题就是如果在服务端,修改了一个接口的签名实现,如增加一个字段,或者删除一个字段.在这种情况下,在默认的配置中,就会报以下的错误信息: org.apa ...

  8. SharePoint 2013 中自定义WCF服务

    在使用SharePoint2013的时候,如果其他客户端 API 的组合不足,可以通过自定义 Web 服务扩展 SharePoint.默认情况下,SharePoint 2013 不仅支持创建自定义 A ...

  9. 浅析在QtWidget中自定义Model

    Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的功能上的分离给了开发人员更大的弹性来定制数据项的表示,它也提供一个标准的model接 ...

随机推荐

  1. Django框架基础知识07-常用查询及表关系的实现

    1.常用的模型字段类型 https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types 2.字段的常用参数 官方文档:http ...

  2. Ducci Sequence解题报告

    A Ducci sequence is a sequence of n-tuples of integers. Given an n-tuple of integers (a1, a2, ... ,  ...

  3. windows操作笔记

    使用服务或其他windows应用的过程中,可能会遇到莫名其妙的错误,这时候从控制面板中,找到管理工具,打开事件查看器,或者通过计算机管理,找到日志中的记录,如果是代码错误,会给出提示信息,比如之前在写 ...

  4. 基于 WPF + Modern UI 的 公司OA小助手 开发总结

    前言: 距离上一篇博客,整整一个月的时间了.人不能懒下来,必须有个阶段性的总结,算是对我这个阶段的一个反思.人只有在总结的过程中才会发现自己的不足. 公司每天都要在OA系统上上班点击签到,下班点击签退 ...

  5. grunt 使用比较

    http://www.cnblogs.com/yexiaochai/p/3603389.html 最全的uglify使用DEMO http://www.cnblogs.com/artwl/p/3449 ...

  6. jquery怎么获得ul中li的个数

  7. HDU-1041-Computer Transformation,大数递推,水过~~

                                                                                  Computer Transformatio ...

  8. hrbust-1909理工门外的树,不用线段数,贪心思路~~

    理工门外的树 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 605(125 users) Total Accepted: 154(11 ...

  9. To_Date函数用法

    spl> select * from emp          where dates          between          to_date('2007-06-12 10:00:0 ...

  10. 字符串常量与const常量内存区(——选自陈皓的博客)

    1. 一个常见的考点: char* p = "test"; 那么理利用指针p来改变字符串test的内容都是错误的非法的. 例如: p[0] = 's'; strcpy(p, &qu ...