zoukankan      html  css  js  c++  java
  • 5.webService拦截器

    CXF为什么要设计拦截器?

      为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器。

    拦截器分类

      1.按所处的位置分:服务器端拦截器,客户端拦截器

      2.按消息的方向分:入拦截器,出拦截器

      

      3.按定义者分:系统拦截器,自定义拦截器

      3.1系统拦截器:

      LoggingInInterceptor(系统日志入拦截器类)

      LoggingOutInterceptor(系统日志出拦截器类)

    ***server***
    //SEI
    @WebService
    public interface HelloWS {
    
        @WebMethod
        public String sayHello(String name);
    }
    
    //SEI implement
    @WebService
    public class HelloWSImpl implements HelloWS {
    
        @Override
        public String sayHello(String name) {
            return "hello: "+name;
        }
    }
    
    //publish
    public class RealeaseWS {
    
        public static void main(String[] args) {
            String address = "http://localhost:8989/WebService_Server";
            Endpoint endpoint = Endpoint.publish(address, new HelloWSImpl());
            EndpointImpl endpointImpl = (EndpointImpl)endpoint;
            //服务器的的入拦截器
            List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
            //将系统日志入拦截器类添加到入拦截器集合中
            inInterceptors.add(new LoggingInInterceptor());
            
            //服务器的的出拦截器
            List<Interceptor<? extends Message>> outInterceptors = endpointImpl.getOutInterceptors();
            //将系统日志出拦截器类添加到出拦截器集合中
            outInterceptors.add(new LoggingOutInterceptor());
            System.out.println("webService发布成功!");
        }
    }
    ***client***
    //生成客户端代码步骤省略。。。
    //客户端调用服务器方法测试程序
    public class TestWebService {
    
        public static void main(String[] args) {
            HelloWSImplService factory = new HelloWSImplService();
            HelloWSImpl helloWSImpl = factory.getHelloWSImplPort();
            
            //在调用服务器方法前配置拦截器
            //获取发送请求的客户端对象
            Client client = ClientProxy.getClient(helloWSImpl);
            
            //客户端的系统日志出拦截器
            List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
            outInterceptors.add(new LoggingOutInterceptor());
            //客户端的系统日志入拦截器
            List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();
            inInterceptors.add(new LoggingInInterceptor());
            
            String result = helloWSImpl.sayHello("webService");
            System.out.println(result);
        }
    }

    执行程序后日志:

    1.首先是从客户端发送请求给服务器,先是发出请求给服务器被拦截(客户端出拦截器),服务器返回响应数据后又被客户端拦截器拦截(客户端入拦截器),拦截信息如下:
    一月 26, 2016 10:32:44 下午 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
    INFO: Creating Service {http://server.webService.com/}HelloWSImplService from WSDL: http://localhost:8989/WebService_Server?wsdl
    一月 26, 2016 10:32:45 下午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
    INFO: Outbound Message
    ---------------------------
    ID: 1
    Address: http://localhost:8989/WebService_Server
    Encoding: UTF-8
    Content-Type: text/xml
    Headers: {Accept=[*/*], SOAPAction=[""]}
    Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://server.webService.com/"><arg0>webService</arg0></ns2:sayHello></soap:Body></soap:Envelope>
    --------------------------------------
    一月 26, 2016 10:32:45 下午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
    INFO: Inbound Message
    ----------------------------
    ID: 1
    Response-Code: 200
    Encoding: UTF-8
    Content-Type: text/xml;charset=UTF-8
    Headers: {Content-Length=[230], content-type=[text/xml;charset=UTF-8], Server=[Jetty(7.5.4.v20111024)]}
    Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://server.webService.com/"><return>hello: webService</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
    --------------------------------------
    hello: webService
    2.服务器接收到客户端请求后,该请求先是被拦截(服务器入拦截器),接着服务器接收请求并执行后,将数据发回给客户端又被拦截(服务器出拦截器),该拦截信息为:
    一月 26, 2016 10:20:35 下午 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
    INFO: Creating Service {http://server.webService.com/}HelloWSImplService from class com.webService.server.HelloWS
    一月 26, 2016 10:20:38 下午 org.apache.cxf.endpoint.ServerImpl initDestination
    INFO: Setting the server's publish address to be http://localhost:8989/WebService_Server
    一月 26, 2016 10:20:38 下午 org.eclipse.jetty.server.Server doStart
    INFO: jetty-7.5.4.v20111024
    一月 26, 2016 10:20:38 下午 org.eclipse.jetty.server.AbstractConnector doStart
    INFO: Started SelectChannelConnector@localhost:8989 STARTING
    一月 26, 2016 10:20:38 下午 org.eclipse.jetty.server.handler.ContextHandler startContext
    INFO: started o.e.j.s.h.ContextHandler{,null}
    webService发布成功!
    一月 26, 2016 10:32:44 下午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
    INFO: Inbound Message
    ----------------------------
    ID: 1
    Address: http://localhost:8989/WebService_Server?wsdl
    Encoding: UTF-8
    Http-Method: GET
    Content-Type: text/xml
    Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[localhost:8989], Pragma=[no-cache], User-Agent=[Apache CXF 2.5.9]}
    --------------------------------------
    一月 26, 2016 10:32:45 下午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
    INFO: Inbound Message
    ----------------------------
    ID: 2
    Address: http://localhost:8989/WebService_Server
    Encoding: UTF-8
    Http-Method: POST
    Content-Type: text/xml; charset=UTF-8
    Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[203], content-type=[text/xml; charset=UTF-8], Host=[localhost:8989], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.5.9]}
    Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://server.webService.com/"><arg0>webService</arg0></ns2:sayHello></soap:Body></soap:Envelope>
    --------------------------------------

      3.2自定义拦截器

      案例:使用自定义拦截器,实现用户名和密码的权限,即访问权限控制!

        需要的拦截器:客户端的出拦截器和服务器的入拦截器

      说明:自定义拦截器都从AbstractPhaseIntercepter继承

      问题:为什么客户端需要设置拦截器?

        因为客户端拦截器能得到客户端的用户名和密码,并且将用户名和密码设置到请求头中,这样服务器接收请求时才能获取到用户名和密码,并且根据得到的用户名和密码来做出验证!

    ***客户端拦截器***
    public class AccountInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
    
        private String name;
        private String password;
        
        public AccountInterceptor(String name,String password) {
            //Phase值决定了拦截器什么时候拦截到消息
            //PRE_PROTOCOL准备请求时拦截
            super(Phase.PRE_PROTOCOL);
            this.name = name;
            this.password = password;
        }
    
        //一旦被拦截,首先调用此方法
        @SuppressWarnings("deprecation")
        @Override
        public void handleMessage(SoapMessage msg) throws Fault {
            List<Header> headers = msg.getHeaders();
            //在客户端请求时,会将用户名密码带过去
            //怎么带用户名和密码到服务器,将用户名和密码设置在请求头中
            org.w3c.dom.Document document = DOMHelper.createDocument();
            Element ele = document.createElement("account");//创建标签<account></account>
            
            Element eleName = document.createElement("name");//创建标签<name></name>
            eleName.setTextContent(name);//给<name>设值,值为客户端传进来的用户名
            ele.appendChild(eleName);
            
            Element elePwd = document.createElement("password");//创建标签<password></password>
            elePwd.setTextContent(password);//给<password>设值,值为客户端传进来的密码
            ele.appendChild(elePwd);
            //设置标签<account>的account
            headers.add(new Header(new QName("account"),ele));
            //如果拦截了,打印以下信息!
            System.out.println("客户端拦截了");
        }
    }
    ***添加自定义拦截器到客户端出拦截器中***
    public class TestWebService {
    
        public static void main(String[] args) {
            HelloWSImplService factory = new HelloWSImplService();
            HelloWSImpl helloWSImpl = factory.getHelloWSImplPort();
            
            //设置用户名和密码
            String name = "webService";
            String password = "123456";
            
            //在调用服务器方法前配置拦截器
            //获取发送请求的客户端对象
            Client client = ClientProxy.getClient(helloWSImpl);
            
            //添加自定义拦截器到客户端出拦截器中
            List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
            outInterceptors.add(new AccountInterceptor(name,password));
            
            String result = helloWSImpl.sayHello("webService");
            System.out.println(result);
        }
    }

    *****************以上是客户端********************

    *****************以上是服务器********************

    //服务器拦截器
    public class CheckAccountInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
    
        public CheckAccountInterceptor() {
            super(Phase.PRE_PROTOCOL);
    
        }
    
        @Override
        public void handleMessage(SoapMessage message) throws Fault {
            //获取客户端请求头
            //account为客户端设置的qname
            Header header = message.getHeader(new QName("account"));
            if(header != null){
                Element account = (Element) header.getObject();
                //通过标签名获取值<name></name>
                String name = account.getElementsByTagName("name").item(0).getTextContent();
                String password = account.getElementsByTagName("password").item(0).getTextContent();
                if("webService".equals(name) && "123456".equals(password)){
                    System.out.println("验证通过......");
                }
            }
            System.out.println("没有通过拦截器!");
            throw new Fault(new RuntimeException("用户名或者密码错误!"));
        }
    }
    //将自定义拦截器添加到服务器的入拦截器
    public class RealeaseWS {
    
        public static void main(String[] args) {
            String address = "http://localhost:8989/WebService_Server";
            Endpoint endpoint = Endpoint.publish(address, new HelloWSImpl());
            EndpointImpl endpointImpl = (EndpointImpl)endpoint;
            //将自定义拦截器添加到服务器的入拦截器
            List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
            inInterceptors.add(new CheckAccountInterceptor());
            System.out.println("webService发布成功!");
        }
    }

    运行程序:

      如果没有通过,则出现以下信息:

    客户端拦截了
    Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 用户名或者密码错误!
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
        at com.sun.proxy.$Proxy27.sayHello(Unknown Source)
        at com.test.TestWebService.main(TestWebService.java:34)
    Caused by: org.apache.cxf.binding.soap.SoapFault: 用户名或者密码错误!
  • 相关阅读:
    1.Vue.js的常用指令
    爬虫
    对key中有数字的字典进行排序
    微信公众号服务器验证的坑
    Linux之正则表达式grep
    Oracle之select
    Linux之文件与目录管理
    Linux之vim、压缩与解压缩
    Linux之文件权限、用户管理
    Oracle学习入门
  • 原文地址:https://www.cnblogs.com/Json1208/p/5161912.html
Copyright © 2011-2022 走看看