最近搞有个webservice的client需要开发,因为看了camel一段时间,也知道cxf这个webservice的框架,所以这次就学习下试试吧。这里记录一下使用过程中的一些记录。
1.通过使用cxf的wsdl2java工具,将wsdl转换成java类,
这个工具有几个参数,我使用的是:
wsdl2java -all -exsh true -d src xxxx.wsdl
这里-exsh需要注意,默认为false,表示生成的java接口方法中,不带soap head的参数,我开始没有设置,后来在处理soap response的head时候遇到问题,就把这个设置成了true。
具体查看http://cxf.apache.org/docs/wsdl-to-java.html
2.spring配置cxf的client
<bean id="authHead" class="com.elitecrm.quartz.task.MayorHotline.AddSoapHeadInterceptor"> <property name="userName"><value>Admin</value></property> <property name="password"><value>123456</value></property> </bean> <jaxws:client id="jaxwsClient" serviceClass="cn.gov.wuxi.MayorHotlineSoap" address="http://127.0.0.1:8080/MayorHotline/MayorHotline.asmx?wsdl" > <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> <ref bean="authHead"/> </jaxws:outInterceptors> </jaxws:client>
jaxws:client标签,可以轻松配置一个webservice client 其中还可以配置interceptors,一开始我不知道-exsh这个参数的时候,就通过这个authHead来添加soap head。
interceptors编写时候,需要注意构造函数中需要提供Phase,本来不知道,一直看不明白为啥日志里一个warning说缺少Phase然后就不添加这个interceptor。
Phase这个类在org.apache.cxf.phase中有定义,定义了多个常量,表示webservice发出请求或者接受请求过程中的不同阶段。
自己定义的interceptor需要实现org.apache.cxf.interceptor.Interceptor接口中的handleMessage方法:
public void handleMessage(SoapMessage sm) throws Fault { Document doc=DOMUtils.createDocument(); Element userName=doc.createElement("UserName"); userName.setTextContent(this.userName); Element passWord=doc.createElement("PassWord"); passWord.setTextContent(this.password); Element root=doc.createElementNS("http://www.wuxi.gov.cn/", "AuthHeader"); root.appendChild(userName); root.appendChild(passWord); QName qname=new QName("RequestSOAPHeader"); SoapHeader head=new SoapHeader(qname,root); List<Header> headers=sm.getHeaders(); headers.add(head); }
3.通过Holder来处理soap head
Holder<CustomHeader> customHeaderHolder = new Holder<CustomHeader>(); ArrayOfAskAnswerMainEntity aaames=service.getInsertAskAnswerMainList(projectId,customHeaderHolder); CustomHeader cHeader=customHeaderHolder.value;
这里的CustomHeader就是生成的webservice接口中定义的
@WebParam(name = "CustomHeader", targetNamespace = "http://www.wuxi.gov.cn/", mode = WebParam.Mode.OUT, header=true) javax.xml.ws.Holder<CustomHeader> customHeaderHolder
通过传递Holder到接口方法,就能在customHeaderHolder.value获取到soap response中的head对象
cxf还有太多要学习,这里只是第一次使用,便于以后查看。