CXF使用Interceptor处理头信息

(三)

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

猜你喜欢

转载自zxc3375.iteye.com/blog/2018334