cxf拦截器

cxf有一些内置的拦截器,先熟悉一下cxf添加拦截器的流程。

package com.bxw.test;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

import com.bxw.service.Service;
import com.bxw.service.impl.ServiceImpl;

public class Test {
    public static void main(String[] args) {
        System.out.println("web service start");
        Service implementor = new ServiceImpl();
        String address = "http://localhost:9095/helloWorld";
//         Endpoint.publish(address, implementor);  // JDK实现

       JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
       factoryBean.setAddress(address); // 设置暴露地址
       factoryBean.setServiceClass(Service.class); // 接口类
       factoryBean.setServiceBean(implementor); // 设置实现类
       factoryBean.getInInterceptors().add(new LoggingInInterceptor());//添加in日志信息
       factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());//添加out日志信息
       factoryBean.create();
    }
}

服务端添加拦截器:

factoryBean.getInInterceptors().add(new LoggingInInterceptor());//添加in日志信息.

factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());//添加out日志信息.

客户端是无法直接添加拦截器的,需要先用代理获得一个客户端:

package com.bxw.test;

import java.util.List;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;

import com.bxw.ws.MyRole;
import com.bxw.ws.Role;
import com.bxw.ws.Service;
import com.bxw.ws.ServiceService;

public class ClientTest {
    public static void main(String[] args) {
        ServiceService ss = new ServiceService();
        Service port = ss.getServicePort();
        //客户端添加拦截器
        Client client = ClientProxy.getClient(port);
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getInInterceptors().add(new LoggingOutInterceptor());

        List<MyRole> roles = port.getRoles().getItem();
        for(MyRole r:roles){
            List<Role> ls = r.getValue();
            for(Role role:ls){
                System.out.println("id:"+role.getId()+" "+"rolename:"+role.getRoleName());
            }
        }
    }
}

自定义拦截器:

使用拦截器进行权限的认证。自定义拦截器需要继承AbstractPhaseInterceptor<SoapMessage>,其中SoapMessage是用来封装soap消息:服务端:

发布时添加拦截器:

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

自定义拦截器:

package com.bxw.entity;

import java.util.List;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MyIntercepter extends AbstractPhaseInterceptor<SoapMessage>{

    public MyIntercepter() {
        super(Phase.PRE_INVOKE);    //调用之前先调用拦截器
    }

    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headers = message.getHeaders();
        if(headers==null || headers.size()==0){
            throw new Fault(new IllegalArgumentException("没有headers,拦截器拦截"));
        }
        Header header = headers.get(0);
        Element elem = (Element) header.getObject();
        NodeList userList = elem.getElementsByTagName("user");
        NodeList pwdList = elem.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(!("admin".equals( username)) || !("123".equals(password))){
            throw new IllegalArgumentException("用户名或密码错误");
        }
    }
}

客户端访问服务时会传过来一个soap消息,我们会将用户名和密码封装到头部中传过来,通过解析soap消息中头部的数据,来进行身份认证。

客户端访问服务端前添加拦截器:

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

自定义拦截器:

package com.bxw.entity;

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class AddHeaderIntercepter extends AbstractPhaseInterceptor<SoapMessage>{

    private String username;
    private String password;

    public AddHeaderIntercepter(String name,String password) {
        super(Phase.PREPARE_SEND);
        this.username = name;
        this.password = password;
    }

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

        //定义三个对象
        Element elem = doc.createElement("authHeader");
        Element userElem = doc.createElement("user");
        Element passElem = doc.createElement("password");

        userElem.setTextContent(username);
        passElem.setTextContent(password);
        elem.appendChild(userElem);
        elem.appendChild(passElem);

        headers.add(new Header(new QName("head"), elem));

    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

首先通过构造函数将用户名和密码传进去,然后获取将要发送的soap消息的头部,紧接着人为构造出几个元素,将用户名和密码封装到元素中去,并放到soap消息的头部,这样soap消息就会携带这个用户名和密码的消息了

时间: 2024-10-11 12:20:15

cxf拦截器的相关文章

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

WebService系列文章: [WebService]带你走进webservice的世界 [WebService]自定义WebService服务及其调用 [WebService]wsdl配置详解以及使用注解修改wsdl配置 [WebService]CXF处理javaBean等复合类型以及Map等复杂类型的数据 CXF的拦截器和以前学过的servlet的拦截器类似的,都是在开始或结束切入一段代码,执行一些逻辑之类的.我们可以在调用ws服务前设置拦截器,也可以在调用ws服务后设置拦截器,当然了,拦

CXF拦截器介绍及自定义拦截器实现

CXF拦截器是功能的主要实现单元,也是主要的扩展点,可以在不对核心模块进行修改的情况下,动态添加功能.当服务被调用时,会经过多个拦截器链(Interceptor Chain)处理,拦截器链在服务输入(IN)或输出(OUT)阶段实现附加功能,拦截器可以在客户端加入,也可以在服务端加入. 拦截器链的阶段: 拦截器链有多个阶段,每个阶段都有多个拦截器.拦截器在拦截器链的哪个阶段起作用,可以在拦截器的构造函数中声明. 输入拦截器链有如下几个阶段,这些阶段按照在拦截器链中的先后顺序排列. 阶段名称 阶段功

CXF拦截器(Interceptor)LoggingInInterceptor

Interceptor是CXF架构中一个重要的功能.你可以在不对核心模块进行修改的情况下,动态添加很多功能(你可以想象Struts2拦截器的优点).这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理. CXF已经实现了很多种拦截器,很多已经在发布.访问Web 服务时已经默认添加到拦截器链.一般情况下, 我们自己的拦截器只要继承AbstractPhaseInte

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

下面具体的webservice实现类直接用的是上面的,这里不再说明 CXF拦截器使用,创建一个使用SOAPHeader的安全验证   xml格式: <soap:Header> <auth:authentication xmlns:auth="http://gd.chinamobile.com//authentication"> <auth:systemID>1</auth:systemID> <auth:userID>test

CXF - 拦截器获取调用方法

没想到要弄这么一个东西. 起初只是想用interceptor记录一下webservice调用日志,后来却被要求在页面展示. 展示容易,但只是展示webservice的地址无法让用户从中明白什么. 那么我可以把url和具体说明作为一对键值,但是这对键值配置到哪里比较好? 文件? db? 我不想每增加一个方法就到别的地方再配置一次键值,写到注解也许是个不错的方法. 这就需要我在方法被调用后在获得对应的Method对象. 当然,实现这个效果的方法有很多种,这里主要讲如何在CXF Interceptor

CXF通过拦截器修改请求报文

最近一位做Siebel的同事需要通过Web Service接口调用另外一个系统,对方的Web Service使用的是CXF框架,并提供了WSDL文件. Siebel通过WSDL生成请求报文时报错,而直接通过SoapUI导入WSDL测试是OK的.通过抓取报文发现,两者生成的报文namespace有所不同,Siebel生成的namespace放在节点上,SoapUI生成的namespace放在头上,具体如下: Siebel生成的报文: <SOAP-ENV:Envelope xmlns:SOAP-EN

WebService -- Java 实现之 CXF ( 添加系统预定义的拦截器)

1. 概述 CXF允许我们在webservice的in/out位置添加拦截器.拦截器有两大分类,一类是系统预定义的:另一类是自定义拦截器. 2. 在server端添加拦截器. JaxWsServerFactoryBean wsSvrFactoryBean = new JaxWsServerFactoryBean(); String address = "http://127.0.0.1/helloWorld"; wsSvrFactoryBean.setAddress(address);

CXF 自定义拦截器

------要想添加一个拦截器,目的是调用之前做一个认证,也就是说不是所有的请求都能调用,这样就可以验证了,更安全. 1     在服务端写一个拦截器,public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage>  ,要给一个构造方法(可以确定是什么时候执行这个拦截器,Phase.PRE_INVOKE就是调用之前执行),重写handleMessage方法,因为信息在请求头里面,所以这个方法中有一些解析XML的A

Apache CXF自定义拦截器

为什么设计拦截器?1.为了在webservice请求过程中,能动态操作请求和响应数据,CXF设计了拦截器 拦截器分类: 1.按所处的位置分:服务器端拦截器,客户端拦截器. 2.按消息的方向分:入拦截器,出拦截器. 3.按定义者分:系统拦截器,自定义拦截器. 客户端添加日志拦截器 package com.client.interceptor; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf