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消息就会携带这个用户名和密码的消息了

原文地址:https://www.cnblogs.com/popcornya/p/7401839.html