CXF 入门:CXF拦截器使用,创建一个基于SOAPHeader的安全验证

来源:互联网 发布:网络机顶盒安装软件 编辑:程序博客网 时间:2024/06/05 03:30
ader的安全验证xml格式:<soap:Header><auth:authentication xmlns:auth="http://gd.chinamobile.com//authentication"><auth:systemID>1</auth:systemID><auth:userID>test</auth:userID><auth:password>test</auth:password></auth:authentication></soap:Header>一,首先在服务端创建一个拦截器(被调用端),需要继承org.apache.cxf.phase.AbstractPhaseInterceptor代码如下:import java.util.List;import javax.xml.soap.SOAPException;import org.apache.cxf.binding.soap.SoapHeader;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.headers.Header;import org.apache.cxf.helpers.XMLUtils;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.apache.log4j.Logger;import org.w3c.dom.Element;import org.w3c.dom.NodeList;public class AuthIntercetpr extends AbstractPhaseInterceptor<SoapMessage> {private static final Logger logger = Logger.getLogger(AuthIntercetpr.class);    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";public static final String xml_header_el = "soap:Header";public static final String xml_authentication_el = "auth:authentication";public static final String xml_systemID_el = "auth:systemID";public static final String xml_userID_el = "auth:userID";public static final String xml_password_el = "auth:password";public AuthIntercetpr() {// 指定该拦截器在哪个阶段被激发super(Phase.PRE_INVOKE);}// 处理消息public void handleMessage(SoapMessage message) {logger.info("==================SoapMessage =" + message);// 获取SOAP消息的全部头List<Header> headers = message.getHeaders();if (null == headers || headers.size() < 1) {throw new Fault(new SOAPException("SOAP消息头格式不对哦!"));}for (Header header : headers) {SoapHeader soapHeader = (SoapHeader) header;// 取出SOAP的Header元素Element element = (Element) soapHeader.getObject();logger.info("ELEMENT =" + element.toString());XMLUtils.printDOM(element);NodeList userIdNodes = element.getElementsByTagName(xml_userID_el);NodeList pwdNodes = element.getElementsByTagName(xml_password_el);NodeList systemIdNodes = element.getElementsByTagName(xml_systemID_el);logger.info("############ 打印帐号信息 ##############");logger.info(userIdNodes.item(0) + "="+ userIdNodes.item(0).getTextContent());logger.info(systemIdNodes.item(0) + "="+ systemIdNodes.item(0).getTextContent());logger.info(pwdNodes.item(0) + "="+ pwdNodes.item(0).getTextContent());logger.info("############————————##############");if (null != userIdNodes&& userIdNodes.item(0).getTextContent().equels("test") ) {if (null != pwdNodes&& pwdNodes.item(0).getTextContent().equals("test")) {logger.info("$$$$$$$$ 认证成功");} else {//认证失败则抛出异常,停止继续操作SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");throw new Fault(soapExc);}} else {//认证失败则抛出异常,停止继续操作SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");throw new Fault(soapExc);}}}}二,修改cxf-beans.xml<!--id:随意配,implementor:指定接口具体实现类,address:随意配,访问时会用到,下面会做说明--><!--拦截器--><bean id="authIntercetpr" class="unitTest.AuthIntercetpr"></bean><jaxws:endpoint id="HelloWorldService" implementor="com.ws.HelloWorldServiceImpl"address="/IHelloService"><!-- 在此配置调用当前ws所触发的拦截器--><ref bean="authIntercetpr" /><!--或者直接在这里写<bean  class="unitTest.AuthIntercetpr"></bean>--></jaxws:endpoint>到此服务端工作完毕!!!下面是客户端(调用端)三,这边同样创建一个拦截器,实现org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptorimport java.text.SimpleDateFormat;import java.util.Date;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.helpers.XMLUtils;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.Phase;import org.w3c.dom.Document;import org.w3c.dom.Element;public class AddSoapHeader extends AbstractSoapInterceptor {public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";public static final String xml_header_el = "soap:Header";public static final String xml_authentication_el = "auth:authentication";public static final String xml_systemID_el = "auth:systemID";public static final String xml_userID_el = "auth:userID";public static final String xml_password_el = "auth:password";public AddSoapHeader() {// 指定该拦截器在哪个阶段被激发super(Phase.WRITE);}public void handleMessage(SoapMessage message) throws Fault {SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = new Date();String time = sd.format(date);String userId = "test";String sysId = "1";String password = "test";QName qname = new QName("RequestSOAPHeader");//这个值暂时不清楚具体做什么用,可以随便写Document doc = (Document) DOMUtils.createDocument();Element root = doc.createElement(xml_header_el);Element eSysId = doc.createElement(xml_systemID_el);eSysId.setTextContent(sysId);Element eUserId = doc.createElement(xml_userID_el);eUserId.setTextContent(userId);Element ePwd = doc.createElement(xml_password_el);ePwd.setTextContent(password);Element child = doc.createElementNS(xml_namespaceUR_att,xml_authentication_el);child.appendChild(eSysId);child.appendChild(eUserId);child.appendChild(ePwd);root.appendChild(child);XMLUtils.printDOM(root);// 只是打印xml内容到控制台,可删除SoapHeader head = new SoapHeader(qname, root);List<Header> headers = message.getHeaders();headers.add(head);}}四,具体调用ws的类代码private static final String webServiceConTimeout = "6000";private static final String webServiceRevTimeout = "6000";。。。。。。。        HelloWorldServiceImplService hello = new HelloWorldServiceImplService();          HelloWorldService service = hello.getHelloWorldServiceImplPort();        //以上什么意思请参考:http://learning.iteye.com/admin/blogs/1333223Client clientProxy = ClientProxy.getClient(service);//通过目标ws获取代理//注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发clientProxy.getOutInterceptors().add(ash);// 超时时间设置HTTPConduit http = (HTTPConduit) clientProxy.getConduit();HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();httpClientPolicy.setConnectionTimeout(Integer.valueOf(webServiceConTimeout));httpClientPolicy.setReceiveTimeout(Integer.valueOf(webServiceRevTimeout));httpClientPolicy.setAllowChunking(false);http.setClient(httpClientPolicy);        //以上插入点超时设置方式//下面这行代码是具体调用服务段的deleteTeskTask()CallResult cResult = service.deleteTeskTask("1223");。。客户端代码到此结束五,还有一种方式是通过JaxWsProxyFactoryBean方式,注册拦截器及实例化ws,代码如下:private static final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();AddSoapHeader ash = new AddSoapHeader();ArrayList list = new ArrayList();// 添加soap header 信息list.add(ash);//注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发 factory.setOutInterceptors(list); factory.setServiceClass(HelloWorldService.class);//实例化ws factory.setAddress("http://xxx.xxx.xxx.xxx:8004/services/IHelloService"); Object obj = factory.create(); HelloWorldService service = (HelloWorldService) obj; //下面这行代码是具体调用服务段的deleteTeskTask()CallResult cResult = service.deleteTeskTask("1223");##########这段代码可替代步骤(四)#####
原创粉丝点击