(三)
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(); }
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(); }