CXF添加自定义拦截器

前面我们说到CXF添加内置的拦截器,今天的话,我们来讲下如何添加自定义拦截器;

我们的实例是客户端访问服务端webservice接口要加权限认证。

我们思路先说下。我们可以通过在SOAP消息的Header头信息中添加自定义信息,然后发送到服务端端,服务器端通过获取

Header头消息,然后进行认证;这里的添加消息,和获取消息认证,我们都是通过自定义拦截器来实现;

OK下面我们来实现下:

首先是服务器端:

我们自定义拦截器:MyInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.java1234.interceptor;
 
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 Administrator
 *
 */
public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
 
    public MyInterceptor(){
        // 在调用方法之前调用拦截器
        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("没有Header,拦截器实施拦截"));
        }
        Header firstHeader=headers.get(0);
        Element ele=(Element) firstHeader.getObject();
        NodeList userIds=ele.getElementsByTagName("userName");
        NodeList userPasses=ele.getElementsByTagName("password");
         
        if(userIds.getLength()!=1){
            throw new Fault(new IllegalArgumentException("用户名格式不对"));
        }
         
        if(userPasses.getLength()!=1){
            throw new Fault(new IllegalArgumentException("密码格式不对"));
        }
         
        String userId=userIds.item(0).getTextContent();
        String userPass=userPasses.item(0).getTextContent();
         
        if(!userId.equals("java1234") || ! userPass.equals("123456")){
            throw new Fault(new IllegalArgumentException("用户名或者密码不正确"));
        }
         
    }
}

这里的话,我们主要是获取Header头消息,然后获取userName和password节点,然后获取值,进行权限判断,假如认证不通过,我们抛出异常;

在Server类里,我们要添加一个in 拦截器,在进入的时候,我们要进行验证;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.java1234.webservice;
 
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 
import com.java1234.interceptor.MyInterceptor;
import com.java1234.webservice.impl.HelloWorldImpl;
 
public class Server {
 
    public static void main(String[] args) {
        System.out.println("web service start");  
        HelloWorld implementor = new HelloWorldImpl();  
        String address = "http://10.10.7.18/helloWorld";  
        JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
        factoryBean.setAddress(address); // 设置暴露地址
        factoryBean.setServiceClass(HelloWorld.class); // 接口类
        factoryBean.setServiceBean(implementor); // 设置实现类
        factoryBean.getInInterceptors().add(new LoggingInInterceptor()); // 添加in拦截器 日志拦截器
        factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器
         
        factoryBean.getInInterceptors().add(new MyInterceptor()); // 添加自定义拦截器
        factoryBean.create();      
        System.out.println("web service started");  
    }
}

接下来是修改客户端代码:

我们同样要添加一个自定义拦截器:AddHeaderInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.java1234.interceptor;
 
 
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 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> headers=message.getHeaders();
         
        Document doc=DOMUtils.createDocument();
        Element ele=doc.createElement("authHeader");
        Element idElement=doc.createElement("userName");
        idElement.setTextContent(userName);
        Element passElement=doc.createElement("password");
        passElement.setTextContent(password);
         
        ele.appendChild(idElement);
        ele.appendChild(passElement);
         
        headers.add(new Header(new QName("java1234"),ele));
         
         
    }
 
     
}

这里的话,我们主要是在拦截器里创建头消息;

Client类里我们要修改下,加下Out 拦截器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.java1234.webservice;
 
import java.util.List;
 
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
 
import com.java1234.interceptor.AddHeaderInterceptor;
 
public class Client {
 
    public static void main(String[] args) {
        HelloWorldService service=new HelloWorldService();
        HelloWorld helloWorld=service.getHelloWorldPort();
        org.apache.cxf.endpoint.Client client=ClientProxy.getClient(helloWorld);
        // client.getInInterceptors().add(new LoggingInInterceptor()); // 添加in拦截器 日志拦截器
        client.getOutInterceptors().add(new AddHeaderInterceptor("java1234","123456")); // 添加自定义拦截器
        client.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器
        //System.out.println(helloWorld.say("java1234"));
        /*User user=new User();
        user.setUserName("jack");
        user.setPassword("123456");
        List<Role> roleList=helloWorld.getRoleByUser(user);
        for(Role role:roleList){
            System.out.println(role.getId()+","+role.getRoleName());
        }*/
        MyRoleArray array=helloWorld.getRoles();
        List<MyRole> roleList=array.item;
        for(int i=0;i<roleList.size();i++){
            MyRole my=roleList.get(i);
            System.out.print(my.key+":");
            for(Role r:my.value){
                System.out.print(r.getId()+","+r.getRoleName()+" ");
            }
            System.out.println();
        }
    }
}

OK这样就完整了自定义拦截器实现权限认证;

先运行Server类,和以前一样;

假如我们把  client.getOutInterceptors().add(new AddHeaderInterceptor("java1234","123456")); // 添加自定义拦截器

密码改成 123 

然后运行Client类,会报错;

QQ鎴�浘20160314095323.png

用户名或者密码不正确;

完整代码: http://pan.baidu.com/s/1dEaHNcX

原文地址:https://www.cnblogs.com/grimm/p/12359161.html