CXF提供了Interceptor拦截器链对SOAP消息进行拦截处理
拦截器分为不同的Phase,各个Phase又有自己的拦截器链,参考http://cxf.apache.org/docs/interceptors.html
在客户端加入头信息
头信息为一个字符串
编写interceptor
PHASE:WRITE
package com.hqh.ws.cxf.interceptor;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.phase.Phase;
public class LicenseOutInterceptor extends AbstractSoapInterceptor{
/**
* 指定加入拦截器到某个阶段
* @param p
*/
public LicenseOutInterceptor() {
super(Phase.WRITE);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
try {
//创建QName
String namespaceURI = "http://ws.cxf.hqh.com";
String localPart = "license";
String prefix = "ns";
QName qname = new QName(namespaceURI, localPart, prefix);
//创建需要使用header进行传输的对象
String sendObj = "license for webservice";
//创建DataBinding
DataBinding dataBinding = new JAXBDataBinding(String.class);
//创建Header
Header header = new Header(qname, sendObj, dataBinding);
//将header加入到SOAP头集合中
headers.add(header);
} catch (JAXBException e) {
e.printStackTrace();
throw new Fault(e);
}
}
}
调用服务时加入interceptor
/**
* 使用interceptor加入header
*/
@Test
public void test03() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(IMyService.class);
factory.setAddress("http://localhost:8888/cxf/ws?wsdl");
//打印发出的消息
factory.getOutInterceptors().add(new LoggingOutInterceptor());
//加入自定义的拦截器
factory.getOutInterceptors().add(new LicenseOutInterceptor());
//获取服务对象
IMyService service = (IMyService)factory.create();
//调用服务
String reply = service.sayHello("李思思");
System.out.println(reply);
System.exit(0);
}
头信息为一个对象
package com.hqh.ws.cxf.model;
public class User {
private String name;
private String pwd;
public User() {
super();
}
public User(String name, String pwd) {
super();
this.name = name;
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
package com.hqh.ws.cxf.interceptor;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.phase.Phase;
import com.hqh.ws.cxf.model.User;
public class LicenseOutInterceptor extends AbstractSoapInterceptor{
/**
* 指定加入拦截器到某个阶段
* @param p
*/
public LicenseOutInterceptor() {
super(Phase.WRITE);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
try {
//创建QName
String namespaceURI = "http://ws.cxf.hqh.com";
String localPart = "license";
String prefix = "ns";
QName qname = new QName(namespaceURI, localPart, prefix);
//创建需要使用header进行传输的对象
//String sendObj = "license for webservice";
//头信息为一个对象
User user = new User("admin","admin1");
//创建DataBinding
//DataBinding dataBinding = new JAXBDataBinding(String.class);
DataBinding dataBinding = new JAXBDataBinding(User.class);
//创建Header
//Header header = new Header(qname, sendObj, dataBinding);
Header header = new Header(qname, user, dataBinding);
//将header加入到SOAP头集合中
headers.add(header);
} catch (JAXBException e) {
e.printStackTrace();
throw new Fault(e);
}
}
}
客户端发出的SOAP消息
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <ns:license xmlns:ns="http://ws.cxf.hqh.com"> <name>admin</name> <pwd>admin1</pwd> </ns:license> </soap:Header> <soap:Body> <ns2:sayHello xmlns:ns2="http://cxf.ws.hqh.com/"> <name>李思思</name> </ns2:sayHello> </soap:Body> </soap:Envelope>
服务端使用拦截器获取头信息
PHASE:UNMARSHALLER
package com.hqh.ws.cxf.interceptor;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.soap.SOAPException;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import com.hqh.ws.cxf.model.User;
public class licenseInIntercptor extends AbstractSoapInterceptor{
/**
* 指定拦截器使用的阶段
* 这里是服务端对header的拦截处理,指定到UNMARSHAL阶段
* 注意:不要指定到READ阶段,READ阶段获取到的是xml数据,还不能从message对象中获取到header的相关信息
* 在unmarshaller将xml转换为对象之后使用拦截器,才能从header对象中获取到数据
* @param p
*/
public licenseInIntercptor() {
super(Phase.UNMARSHAL);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
//获取所有的header
List<Header> headers = message.getHeaders();
System.out.println("headers size:"+headers.size());
try {
//服务端能通过DataBinding进行对象的自动转换吗?在read/unmarshaller时加入?
//DataBinding binding = new JAXBDataBinding(User.class);
for(Header head : headers) {
String localPart = head.getName().getLocalPart();
System.out.println("当前头信息节点名称:"+localPart);
if("license".equals(localPart)) {
//获取cxf拦截器转换得到的头信息对象
Object obj = head.getObject();
//注意:这里获取到的obj并不是客户端指定的User对象!
System.out.println(obj instanceof User);
Element element = (Element)obj;
String name = element.getElementsByTagName("name").item(0).getTextContent();
String pwd = element.getElementsByTagName("pwd").item(0).getTextContent();
if("admin".equals(name) && "admin".equals(pwd)) {
System.out.println("验证成功");
} else {
SOAPException ex = new SOAPException("认证信息错误!");
throw new Fault(ex);
}
}
}
} catch (Exception e) {
//e.printStackTrace();
throw new Fault(e);
}
}
}
服务端发布服务时加入指定的拦截器
/**
* 使用CXF发布服务
*/
public static void startServerByCXF() {
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(IMyService.class);
svrFactory.setAddress("http://localhost:8888/cxf/ws");
svrFactory.setServiceBean(new MyServiceImpl());
//打印进入的消息
svrFactory.getInInterceptors().add(new LoggingInInterceptor());
//打印发出的消息
svrFactory.getOutInterceptors().add(new LoggingOutInterceptor());
/**
* 加入服务端的Handler处理客户端传递的头信息
*/
// List<Handler> handlers = new ArrayList<Handler>();
// handlers.add(new LicenseHandler());
// svrFactory.setHandlers(handlers);
/**
* 加入对头信息的拦截器
*/
svrFactory.getInInterceptors().add(new licenseInIntercptor());
svrFactory.create();
}