【WebService】CXF拦截器的设置以及自定义CXF拦截器

WebService系列文章:

【WebService】带你走进webservice的世界

【WebService】自定义WebService服务及其调用

【WebService】wsdl配置详解以及使用注解修改wsdl配置

【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据

  CXF的拦截器和以前学过的servlet的拦截器类似的,都是在开始或结束切入一段代码,执行一些逻辑之类的。我们可以在调用ws服务前设置拦截器,也可以在调用ws服务后设置拦截器,当然了,拦截器也可以添加多个,CXF中有自己内置的拦截器,先来写个简单CXF自带的拦截器实例熟悉一下在CXF中如何添加,然后再来自定义CXF拦截器。

1. CXF内置的拦截器设置

还是使用上一节的ws,在原来的基础上添加以下拦截器,如下:

启动之后,客户端访问一下,看服务端控制台的输出(为了清楚点,我就不缩小了):

  可以看到,请求的时候会被拦截器拦截,请求结束也会被拦截,从打印的日志消息可以看出,发送的是soap消息,返回的数据由于截屏的范围我就不截取了,这是在服务端添加的拦截器。

  那客户端如何添加拦截器呢?由于client端无法直接获取拦截器组,所以我们需要首先获取一个client的代理,然后通过这个代理来获取拦截器组,如下:

客户端访问一下,看下客户端控制台的输出结果(为了清楚点,我就不缩小了):

  可以看出,客户端如果设置拦截器的话,也会打印出日志消息,而且客户端和服务端的拦截器执行顺序刚好相反。这就是CXF内置的拦截器,下面我们来自定义CXF的拦截器。

2. 自定义CXF拦截器

  自定义拦截器的话,我们来弄个需求,使用拦截器进行权限的认证。自定义拦截器需要继承AbstractPhaseInterceptor<SoapMessage>,其中SoapMessage是用来封装soap消息的,我们具体来看下如何自定义CXF拦截器,首先看服务端,在上面的代码的定义的两个内置拦截器下面添加一个自定义拦截器即可:

factoryBean.getInInterceptors().add(new MyInterceptor());

然后重点是这个MyInterceptor,如下:

public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage>  {

    public MyInterceptor() {
        super(Phase.PRE_INVOKE); //在调用方法之前调用自定义拦截器

    }

    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headers = message.getHeaders(); //根据soap消息获取头部
        if(headers == null && headers.size() == 0) {
            throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"));
        }
        Header firstHeader = headers.get(0); //我们等会只传一个头部过来
        Element elm = (Element) firstHeader.getObject();//将该头部转成一个Element对象
        NodeList userList = elm.getElementsByTagName("username"); //根据标签获取值
        NodeList pwdList = elm.getElementsByTagName("password");

        // 进行身份认证
        if(userList.getLength() != 1) {//只有一个用户
            throw new Fault(new IllegalArgumentException("用户名格式不对"));
        }
        if(pwdList.getLength() != 1) {//只有一个密码
            throw new Fault(new IllegalArgumentException("密码格式不对"));
        }
        String username = userList.item(0).getTextContent(); //因为就一个,所以获取第一个即可
        String  password= pwdList.item(0).getTextContent();

        if(!username.equals("admin") || !password.equals("123")) {
            throw new Fault(new IllegalArgumentException("用户名或者密码错误"));
        }
    }

}

  上面的代码逻辑很简单,等会儿客户端会传过来一个soap消息,我们会将用户名和密码封装到头部中传过来,那么在这边,通过解析soap消息中头部的数据,来进行身份认证。所以接下来完成客户端那边的拦截器。

  客户端这边要自定义一个out拦截器了,因为这边是发送数据,同上,首先在原来客户端定义的两个内置CXF拦截器上面添加一个自定义拦截器,如下:

client.getOutInterceptors().add(new AddHeaderInterceptor("admin", "123"));//添加自定义拦截器

在自定义拦截器中,将用户名和密码传进去,重点来看一下这个自定义拦截器,如下:

public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    private String username;
    private String password;

    public AddHeaderInterceptor(String username, String password) {
        super(Phase.PREPARE_SEND); //准备发送soap消息的时候调用拦截器
        this.username = username;
        this.password = password;
    }

    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headerList = message.getHeaders();
        Document doc = DOMUtils.createDocument();

        // 定义三个对象
        Element elm = doc.createElement("authHeader");
        Element userElm = doc.createElement("username");
        Element pwdElm = doc.createElement("password");

        // 给用户名和密码对象赋值
        userElm.setTextContent(username);
        pwdElm.setTextContent(password);

        // 将用户名和密码的对象添加到elm中
        elm.appendChild(userElm);
        elm.appendChild(pwdElm);

        headerList.add(new Header(new QName("head"), elm));//往soap消息头部中添加这个elm元素
    }

}

  从上面的代码中可以看出,首先通过构造函数将用户名和密码传进去,然后获取将要发送的soap消息的头部,紧接着认为构造出几个元素,将用户名和密码封装到元素中去,并放到soap消息的头部,这样等会soap消息就会携带这个用户名和密码的消息了,这样就能在上面的服务端取出,进行身份认证了,这样就前后连通了起来。测试结果我就不贴了,可以查看控制台打印的结果,重点看一下soap消息,里面封装好了一个DOM对象,封装了用户名和密码。



—–乐于分享,共同进步!

—–我的博客主页:http://blog.csdn.net/eson_15

时间: 2024-10-26 01:26:44

【WebService】CXF拦截器的设置以及自定义CXF拦截器的相关文章

自定义注解+拦截器实现权限控制

根据5.2中的讲解,当监控high priority queue的PDSP channel设定好后,那么与之对应的event就知道了(PDSP channel与event一一对应)(注意5.x讲的是中断的配置,并不是exception的配置,4.x讲的是exception) 中断event与ISR配置代码如下,目的是使event与ISR建立联系: /*Configure event*/ EventCombinerEventConfig( systemEvent,  (TEventCombiner

bos项目第二天(msyql操作、ssh配置集成、PowerDesinger、自定义登陆拦截器)

项目第二天(完整流程) 1.  第二天 重点内容 搭建SSH 完成框架 以用户管理为例 用户登录 用户退出 修改密码 2.  开发流程 2.1.  业务分析 2.2.  数据库设计 MySQL : 新建 DataBase . 新建用户 User .进行授权 Oracle : 新建用户 User . 创建表空间 . 在表空间进行操作 MySQL 操作步骤 : 步骤: 新建数据库 查看字符集 show variables like '%char%'; client.connection.result

[原创]java WEB学习笔记74:Struts2 学习之路--自定义拦截器,struts内建的拦截器

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

自定义struts2拦截器

二.自定义拦截器 1.编写一个类,实现com.opensymphony.xwork2.interceptor.Interceptor 2.主要实现public String intercept(ActionInvocation invocation) throws Exception{}方法 该方法的返回值就相当于动作的返回值 如果调用了String result = invocation.invoke();得到了动作类的返回的值. public String intercept(ActionI

SpringMVC 自定义一个拦截器

自定义一个拦截器方法,实现HandlerInterceptor方法 public class FirstInterceptor implements HandlerInterceptor{ /** * 该方法在目标方法之前被调用. * 若返回值为 true, 则继续调用后续的拦截器和目标方法. * 若返回值为 false, 则不会再调用后续的拦截器和目标方法. * * 可以考虑做权限. 日志, 事务等. */ @Override public boolean preHandle(HttpServ

Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例

利用Spring的拦截器可以在处理器Controller方法执行前和后增加逻辑代码,了解拦截器中preHandle.postHandle和afterCompletion方法执行时机. 自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法. 然后在spring-mvc.xml中添加拦截器配置,来指定拦截哪些请求. 步骤一: 创建SomeInterceptor拦截器组件 新建一个com.souvc.interceptor包,在该包中新建一个SomeI

自定义一个类加载器

http://www.cnblogs.com/xrq730/p/4847337.html 为什么要自定义类加载器 类加载机制:http://www.cnblogs.com/xrq730/p/4844915.html 类加载器:http://www.cnblogs.com/xrq730/p/4845144.html 这两篇文章已经详细讲解了类加载机制和类加载器,还剩最后一个问题没有讲解,就是 自定义类加载器.为什么我们要自定义类加载器?因为虽然Java中给用户提供了很多类加载器,但是和实际使用比起

使用VideoView自定义一个播放器控件

介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actvity里了,写完一看我靠代码好乱,于是就写了个自定义的播放器控件,支持指定大小,可以横竖屏切换,手动左右滑动快进快退.好了,下面开始. 效果图 效果图有点卡,我也不知道为啥..... VideoView介绍 这个是我们实现视频播放最主要的控件,详细的介绍大家百度就去看,这里介绍几个常用的方法. 用于

SQLHelper——一个自定义SQL帮助器

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Configuration; 6 using System.Data.SqlClient; 7 using System.Data; 8 9 /// <summary> 10 /// 名称: 11 /// 自定义SQL帮助器 12 /// 摘要: 13 /// 提供简化sql操作