webservice概述及cxf在Java开发中应用(五) cxf拦截器

    前言:

    我们发布了一个服务,怎样保证我发布的服务不被所有人调用,用权限控制服务的调用,需要这样做?

    cxf拦截器提供了这样的解决方法。下图来源于疯狂Java—cxf视频教程

    145952_7bqT_252483.png

    从图中可以看出,cxf拦截器分为四种:服务端in,out拦截器;客户端in,out拦截器。

    cxf有自带的拦截器,同时我们也可以自定义拦截器,下面我们编写一个自定义拦截器

package com.dqjb.util;

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;

/**
 * 自定义拦截器
 *  
 * @author wujialing
 * @version V1.20,2015年4月21日 下午3:30:10
 * @see [相关类/方法]
 * @since V1.20
 * @depricated
 */
public class AuthIntercepter extends AbstractPhaseInterceptor<SoapMessage>
{

    public AuthIntercepter()
    {
        //调用之前进行拦截
        super(Phase.PRE_INVOKE);
    }

    //handleMessage里面的形参就是被拦截到的soap消息
    @Override
    public void handleMessage(SoapMessage msg)
        throws Fault
    {
        List<Header> headers =  msg.getHeaders() ;
        if (headers != null && headers.size() > 0)
        {
            Header header = headers.get(0);
            Element element =  (Element)header.getObject();
            NodeList userIds = element.getElementsByTagName("userId");
            NodeList userPasses = element.getElementsByTagName("userPass");
            System.err.println("用户名:"+userIds.item(0).getTextContent());
            System.err.println("密码:"+userPasses.item(0).getTextContent());
            
        }
        System.err.println("调用之前拦截器");
    }
    
}

    自定义拦截器需要继承AbstractPhaseInterceptor<SoapMessage>并且重写handleMessage方法,该方法就是你        拦截的业务逻辑,而构造方法中

super(Phase.PRE_INVOKE);

    这一句代码,就是设置进入拦截器的时机。

    下面分别服务端和客户端添加in和out拦截器:

    服务端:

package com.dqjb.ws;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;

import com.dqjb.util.AuthIntercepter;
import com.dqjb.ws.imlp.HelloWorldImpl;

public class WsPublish
{
    
    public static void main(String[] args)
    {
        HelloWorld helloWorld = new HelloWorldImpl();
        EndpointImpl en = (EndpointImpl)Endpoint.publish("http://10.114.73.30:8080/helloWorld", helloWorld);
        en.getInInterceptors().add(new AuthIntercepter());//添加服务端in拦截器 自定义拦截器
        en.getOutInterceptors().add(new LoggingOutInterceptor());//添加服务端out拦截器 日志拦截器
        System.err.println("发布成功!");
    }
}

    服务端添加拦截器后,我们需要在客户端也加入拦截器,并在soap的header元素中添加用户名,密码信息。

package util;

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.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * 客户端拦截器
 * 
 * @author wujialing
 * @version V1.20,2015年4月21日 下午4:13:33
 * @see [相关类/方法]
 * @since V1.20
 * @depricated
 */
public class AddHeaderIntercepter extends AbstractPhaseInterceptor<SoapMessage>
{
    
    private String userId ;
    
    private String userPass ;

    public AddHeaderIntercepter(String userId, String userPass)
    {
        super(Phase.PREPARE_SEND); //在准备发送soap消息的时候调用
        this.userId = userId; 
        this.userPass = userPass ;
    }

    @Override
    public void handleMessage(SoapMessage msg)
        throws Fault
    {
        List<Header> headers = msg.getHeaders();
        
        //创建一个doc对象
        Document doc = org.apache.cxf.helpers.DOMUtils.createDocument();
        Element ele  = doc.createElement("authHeader");
        
        //此处创建的元素应按照服务端的要求创建
        Element idEle  = doc.createElement("userId");
        idEle.setTextContent(userId);
        Element passEle  = doc.createElement("userPass");
        passEle.setTextContent(userPass);
        ele.appendChild(idEle);
        ele.appendChild(passEle);
        /*
         * 上面代码生成一个XML片段
         */
        headers.add(new Header(new QName("dqjq"), ele));
    }
    
}

    客户端调用时添加拦截器:

package test;

import java.util.List;

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

import util.AddHeaderIntercepter;

import com.dqjb.ws.HelloWorld;
import com.dqjb.ws.Task;
import com.dqjb.ws.User;
import com.dqjb.ws.imlp.HelloWorldWS;

public class TestClient
{
    public static void main(String[] args)
    {
        HelloWorldWS ws= new HelloWorldWS();
        HelloWorld helloWorld = ws.getHelloWorldImplPort();
        //客户端添加拦截器
        Client client = ClientProxy.getClient(helloWorld);
        client.getOutInterceptors().add(new AddHeaderIntercepter("wujialing","123")); //客户端添加自定义拦截器
        client.getOutInterceptors().add(new LoggingOutInterceptor());//添加默认拦截器
        System.err.println(helloWorld.sayHi("OK!"));
        User u = new User() ;
        u.setAge(21);
        u.setName("小明");
        u.setPost("CXY");
        List<Task> tasks = helloWorld.getTaskByUser(u);
        for (Task task : tasks)
        {
            System.out.println(task.getTaskName());
        }
        
        //HashMap<String, Task> result = helloWorld.getAllTasks2();
    }
}

    通过对服务端客户端拦截器的编写及调用,我们即可以实现cxf服务调用权限的实现。

转载于:https://my.oschina.net/wujialing/blog/411836

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值