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

Stella981
• 阅读 533

下面具体的webservice实现类直接用的是上面的,这里不再说明

CXF拦截器使用,创建一个使用SOAPHeader的安全验证  
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所触发的拦截器-->  
        <jaxws:inInterceptors><ref bean="authIntercetpr" /></bean>   
              
        <!--或者直接在这里写<bean  class="unitTest.AuthIntercetpr"></bean>-->  
        </jaxws:inInterceptors>  
</jaxws:endpoint>

到此服务端工作完毕!!!

下面是客户端(调用端)

三,这边同样创建一个拦截器,实现org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor

import 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/1333223  
Client 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");

##########这段代码可替代步骤(四)#####  
  
到此全部工作结束  
具体一些概念还请自己baidu/google

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这