CXF 中自定义SOAPHeader
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中。
服务端拦截器
package hs.cxf.soapHeader; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.NodeList; /** * * @Title:获取soap头信息 * * @Description: * * @Copyright: * * @author zz * @version 1.00.000 * */ public class ReadSoapHeader extends AbstractPhaseInterceptor<SoapMessage> { private SAAJInInterceptor saa = new SAAJInInterceptor(); public ReadSoapHeader() { super(Phase.PRE_PROTOCOL); getAfter().add(SAAJInInterceptor.class.getName()); } public void handleMessage(SoapMessage message) throws Fault { SOAPMessage mess = message.getContent(SOAPMessage.class); if (mess == null) { saa.handleMessage(message); mess = message.getContent(SOAPMessage.class); } SOAPHeader head = null; try { head = mess.getSOAPHeader(); } catch (SOAPException e) { e.printStackTrace(); } if (head == null) { return; } try { //读取自定义的节点 NodeList nodes = head.getElementsByTagName("tns:spId"); NodeList nodepass = head.getElementsByTagName("tns:spPassword"); //获取节点值,简单认证 if (nodes.item(0).getTextContent().equals("wdw")) { if (nodepass.item(0).getTextContent().equals("wdwsb")) { System.out.println("认证成功"); } } else { SOAPException soapExc = new SOAPException("认证错误"); throw new Fault(soapExc); } } catch (Exception e) { SOAPException soapExc = new SOAPException("认证错误"); throw new Fault(soapExc); } } }
配置文件中新增拦截器配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"> <property name="wrapped" value="true" /> <property name="dataBinding" ref="aegisBean" /> </bean> <bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" /> <jaxws:endpoint id="CollectiveServices" implementor="hs.cxf.server.WebServiceSampleImpl" address="/HelloWorld"> <jaxws:inInterceptors> <!-- 日志拦截器 --> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> <!-- 自定义拦截器 --> <bean class="hs.cxf.soapHeader.ReadSoapHeader"/> </jaxws:inInterceptors> <jaxws:serviceFactory> <ref bean="jaxWsServiceFactoryBean"/> </jaxws:serviceFactory> </jaxws:endpoint> </beans>
客户端拦截器:
package hs.cxf.client.SoapHeader; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapHeader; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.headers.Header; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.Phase; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * * @Title:在发送消息前,封装Soap Header 信息 * * @Description: * * @Copyright: * * @author zz * @version 1.00.000 * */ public class AddSoapHeader extends AbstractSoapInterceptor { private static String nameURI="http://127.0.0.1:8080/cxfTest/ws/HelloWorld"; public AddSoapHeader(){ super(Phase.WRITE); } public void handleMessage(SoapMessage message) throws Fault { String spPassword="wdwsb"; String spName="wdw"; QName qname=new QName("RequestSOAPHeader"); Document doc=DOMUtils.createDocument(); //自定义节点 Element spId=doc.createElement("tns:spId"); spId.setTextContent(spName); //自定义节点 Element spPass=doc.createElement("tns:spPassword"); spPass.setTextContent(spPassword); Element root=doc.createElementNS(nameURI, "tns:RequestSOAPHeader"); root.appendChild(spId); root.appendChild(spPass); SoapHeader head=new SoapHeader(qname,root); List<Header> headers=message.getHeaders(); headers.add(head); System.out.println(">>>>>添加header<<<<<<<"); } }
客户端调用时:
package hs.cxf.client; import hs.cxf.client.SoapHeader.AddSoapHeader; import java.util.ArrayList; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; /** * @Title: * * @Description: * * @Copyright: * * @author zz * @version 1.00.000 * */ public class TestClient { /** * 测试1 */ @SuppressWarnings("unchecked") public void testSend1() { try { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); ArrayList<Interceptor> list = new ArrayList<Interceptor>(); // 添加soap header list.add(new AddSoapHeader()); // 添加soap消息日志打印 list.add(new org.apache.cxf.interceptor.LoggingOutInterceptor()); factory.setOutInterceptors(list); factory.setServiceClass(WebServiceSample.class); factory.setAddress("http://127.0.0.1:8080/cxfTest/ws/HelloWorld"); Object obj = factory.create(); System.out.println(obj == null ? "NULL" : obj.getClass().getName()); if (obj != null) { WebServiceSample ws = (WebServiceSample) obj; String str = ws.say("test"); System.out.println(str); str = ws.say("1111"); System.out.println(str); User u = new User(); JAXBElement<String> je = new JAXBElement<String>(new QName( "http://bean.cxf.hs", "name"), String.class, "张三"); u.setName(je); str = ws.sayUserName(u); System.out.println(str); // 通过对象来交互 ReqBean req = new ReqBean(); req.setExp(new JAXBElement<String>(new QName( "http://bean.cxf.hs", "exp"), String.class, "<exp>111<exp>")); req.setSeqId(new JAXBElement<String>(new QName( "http://bean.cxf.hs", "seqId"), String.class, "12345678")); RespBean resp = ws.action(req); System.out.println("resp_id:" + resp.getRespId().getValue()); System.out.println("resp_exp:" + resp.getExp().getValue()); } } catch (Exception ex) { ex.printStackTrace(); } } /** * 测试2 */ @SuppressWarnings("unchecked") public void testSend2() { String webServiceUrl = "http://127.0.0.1:8080/cxfTest/ws/HelloWorld"; String webServiceConTimeout = "60000"; String webServiceRevTimeout = "60000"; JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); ArrayList<Interceptor> list = new ArrayList<Interceptor>(); // 添加soap header 信息 list.add(new AddSoapHeader()); // 添加soap消息日志打印 list.add(new org.apache.cxf.interceptor.LoggingOutInterceptor()); factory.setOutInterceptors(list); factory.setServiceClass(WebServiceSample.class); factory.setAddress(webServiceUrl); WebServiceSample service = (WebServiceSample) factory.create(); //超时时间设置 Client clientP = ClientProxy.getClient(service); HTTPConduit http = (HTTPConduit) clientP.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setConnectionTimeout(Integer .valueOf(webServiceConTimeout)); httpClientPolicy.setReceiveTimeout(Integer .valueOf(webServiceRevTimeout)); httpClientPolicy.setAllowChunking(false); http.setClient(httpClientPolicy); // 通过对象来交互 ReqBean req = new ReqBean(); req.setExp(new JAXBElement<String>(new QName( "http://bean.cxf.hs", "exp"), String.class, "<exp>111<exp>")); req.setSeqId(new JAXBElement<String>(new QName( "http://bean.cxf.hs", "seqId"), String.class, "12345678")); System.out.println(">>>>>>发送消息<<<<<<<<<"); RespBean resp = service.action(req); System.out.println("resp_id:" + resp.getRespId().getValue()); System.out.println("resp_exp:" + resp.getExp().getValue()); } /** * @param args */ public static void main(String[] args) { TestClient tc = new TestClient(); tc.testSend1(); System.out.println(">>>>>>>>>>>>2<<<<<<<<<<<<<"); tc.testSend2(); System.out.println(">>>>>>>>>>>>END<<<<<<<<<<<<<"); } }
CXF 中自定义SOAPHeader的更多相关文章
- Html中自定义鼠标的形状
Html中自定义鼠标的形状 <html> <head> <title>自定义的鼠标形状</title> <meta http-equiv=&quo ...
- 教你一招:在PowerPoint中自定义可输入文本的占位符
日常生活中,当我们设计多媒体课件时,默认的版式其实已经够用了.但是,很多时候,我们需要更加个性一点,所以,我们需要自定义很多东西.本文介绍在PowerPoint中自定义可输入文本的占位符. 一.占位符 ...
- android代码优化----ListView中自定义adapter的封装(ListView的模板写法)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 在Eclipse中自定义类似syso的快捷代码模板
sysout/syso syserr/ syse 点击菜单栏的“Window”->“Preferences”,打开“Preferences”对话框.在Preferences”对话框中点击“Jav ...
- 在.net桌面程序中自定义鼠标光标
有的时候,一个自定义的鼠标光标能给你的程序增色不少.本文这里介绍一下如何在.net桌面程序中自定义鼠标光标.由于.net的桌面程序分为WinForm和WPF两种,这里分别介绍一下. WinForm程序 ...
- .net中自定义过滤器对Response内容进行处理
原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 代码DEMO:http://files.cnblogs.com/ ...
- 在cxf中使用配置避免增加字段导致客户端必须更新、同步实体属性的问题
在使用cxf实现webservice时,经常碰到的问题就是如果在服务端,修改了一个接口的签名实现,如增加一个字段,或者删除一个字段.在这种情况下,在默认的配置中,就会报以下的错误信息: org.apa ...
- SharePoint 2013 中自定义WCF服务
在使用SharePoint2013的时候,如果其他客户端 API 的组合不足,可以通过自定义 Web 服务扩展 SharePoint.默认情况下,SharePoint 2013 不仅支持创建自定义 A ...
- 浅析在QtWidget中自定义Model
Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的功能上的分离给了开发人员更大的弹性来定制数据项的表示,它也提供一个标准的model接 ...
随机推荐
- 使用SqlParameter.SqlDbType和SqlParameter.Size时需要注意的地方
1.DbParameter类是SqlParameter和OracleParameter类的父类.DbParameter.Size用来获取或设置列中数据的最大尺寸(只对文本数据有用). 2.数据类型Ch ...
- bzoj 1500 [NOI 2005] 维修数列
题目大意不多说了 貌似每个苦逼的acmer都要做一下这个splay树的模版题目吧 还是有很多操作的,估计够以后当模版了.... #include <cstdio> #include < ...
- BZOJ3027 - [CEOI2004]Sweet
Portal Description 给出\(n(n\leq10),a,b(a,b\leq10^7)\)与\(\{c_n\}(c_i\leq10^6)\),求使得\(\sum_{i=1}^n x_i ...
- 565. Array Nesting
Problem statement: A zero-indexed array A consisting of N different integers is given. The array con ...
- java打开本地应用程序(调用cmd)---Runtime用法详解
有时候我们需要借助java程序打开电脑自带的一些程序,可以直接打开或者借助cmd命令窗口打开一些常用的应用程序或者脚本,在cmd窗口执行的命令都可以通过这种方式运行. 例如: package cn.x ...
- msp430入门编程40
msp430中C语言的软件工程--前后台程序结构
- Python()- 面向对象三大特性----封装
封装: [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式.[好处] 1. 将变化隔离: 2. 便于使用:3. 提高复用性: 4. 提高安全性:[封装原则] 1. 将 ...
- Scrambled Polygon--poj2007(极角排序模板)
http://poj.org/problem?id=2007 #include<stdio.h> #include<math.h> #include<algorithm& ...
- PostgreSQL 9.3.1 中文手册(解决关键词报错的问题)
http://www.postgres.cn/docs/9.3/sql-keywords-appendix.html
- httpclient请求去掉返回结果string中的多余转义字符
public String doGet() { String uriAPI = "http://XXXXX?str=I+am+get+String"; String result= ...