• (八)CXF添加自定义拦截器


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

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

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

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

    OK下面我们来实现下:

    首先是服务器端:

     

    我们自定义拦截器:MyInterceptor

    package com.wishwzp.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);  
            
        }
    
        /**
         * 拦截获取消息
         */
        @SuppressWarnings("null")
        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 uList=ele.getElementsByTagName("userName");
            NodeList pList=ele.getElementsByTagName("password");
            if(uList.getLength()!=1){
                throw new Fault(new IllegalArgumentException("用户名格式不对"));
            }
            if(pList.getLength()!=1){
                throw new Fault(new IllegalArgumentException("密码格式不对"));
            }
            String userName=uList.item(0).getTextContent();
            String password=pList.item(0).getTextContent();
            
            if(!userName.equals("wishwzp")||!password.equals("123456")){
                throw new Fault(new IllegalArgumentException("用户名或者密码不正确"));
            }
        }
    
    }

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

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

    package com.wishwzp.webservice;
    
    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.wishwzp.interceptor.MyInterceptor;
    import com.wishwzp.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://192.168.0.110/helloWorld";  
            //Endpoint.publish(address, implementor);  // JDK实现   暴露webservice接口
            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

    package com.wishwzp.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> headerList=message.getHeaders();
            
            Document doc=DOMUtils.createDocument();
            Element ele=doc.createElement("authHeader");
            Element uElement=doc.createElement("userName");
            uElement.setTextContent(userName);
            Element pElement=doc.createElement("password");
            pElement.setTextContent(password);
            
            ele.appendChild(uElement);
            ele.appendChild(pElement);
            
            headerList.add(new Header(new QName("wishwzp"),ele));
            
        }
        
        
    
    }

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

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

    package com.wishwzp.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.wishwzp.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("wishwzp","123")); // 添加自定义拦截器
            
            client.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器
            
            //System.out.println(helloWorld.say("wishwzp测试"));
    //        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("wishwzp","123456")); // 添加自定义拦截器

    密码改成 123 

    然后运行Client类,会报错;

    用户名或者密码不正确;

  • 相关阅读:
    Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)
    将生成200 个激活码(或者优惠券)保存到 oracle关系型数据库中
    将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果
    面试笔试题:多表关联的update语句、将in中的查询条件按顺序输出和SQL语句增加列、修改列、删除列
    sql中级到高级
    Linux常用命令
    类的特殊成员方法
    正则表达式的方法匹配规则
    启动ecilpse 报错an error has occurred. see the log file
    访问修饰符
  • 原文地址:https://www.cnblogs.com/wishwzp/p/9916748.html
Copyright © 2020-2023  润新知