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 [email protected]: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: 用户名或者密码错误!
时间: 2024-11-05 15:51:07

5.webService拦截器的相关文章

7.添加基于Spring的WebService拦截器

客户端拦截器: public class AccountInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ private String name; private String password; public AccountInterceptor(String name,String password) { //Phase值决定了拦截器什么时候拦截到消息 //PRE_PROTOCOL准备请求时拦截 super(Phase.P

webservice拦截器

CXF的拦截器 理解 为什么设计拦截器? 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器. 拦截器分类: 按所处的位置分:服务器端拦截器,客户端拦截器 按消息的方向分:入拦截器,出拦截器 按定义者分:系统拦截器,自定义拦截器 基于jdk的webservice没有拦截器的功能实现. 接口方法: import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interfac

WebService拦截器的使用

. WebService自定义拦截器只需要继承AbstractPhaseInterceptor即可 . 编写自定义拦截器之后,需要在发布的类和调用类中添加拦截器,分布使用JaxWsServerFactoryBean实例.getInInterceptors().add(自定义拦截器实例);和 JaxWsProxyFactoryBean.getOutInterceptors().add(自定义拦截器实例),进行拦截器的添加. . 一个简单的用户验证的拦截器,具体的代码如下: ------------

webservice拦截器 查看消息包(soap)

服务端: 1.获取EndpointImpl对象 2.调用EndpointImpl对象中的方法获取In拦截器 3.调用EndpointImpl对象中的方法获取out拦截器 4.添加自己的In拦截器与Out拦截器 LogginInInterceptor:查看收到的消息包 LoggOutInterceptor:查看发出去的消息包 客户端: 需要导入cxf的7个jar包: 1.获取client对象 Client client=ClientProxy.getClient("ws服务组件代理对象"

WebService学习笔记-CXF添加拦截器

Webservice拦截器:在webservice请求过程中,动态操作请求和响应的数据 分类 按照所处的位置分:服务器端拦截器  客户端拦截器 按照消息的方向分:入拦截器  出拦截器 按照定义者分:系统拦截器 自定义拦截器 在服务器端添加拦截器 package com.demo; //注意引入的类一定要正确 import javax.xml.ws.Endpoint; import org.apache.cxf.interceptor.LoggingInInterceptor; import or

WebService -- Java 实现之 CXF ( 添加系统预定义的拦截器)

1. 概述 CXF允许我们在webservice的in/out位置添加拦截器.拦截器有两大分类,一类是系统预定义的:另一类是自定义拦截器. 2. 在server端添加拦截器. JaxWsServerFactoryBean wsSvrFactoryBean = new JaxWsServerFactoryBean(); String address = "http://127.0.0.1/helloWorld"; wsSvrFactoryBean.setAddress(address);

基于CXF框架的webservice简单的SC两端出入拦截器实现。

开发工具:  ECLIPSE(EE) + CXF(2.5.9) (I)可以现在eclipse中使用JDK来创建webservice基础服务.(没有CXF框架的webservice) (1)新建一个java project. (命名为FirstWebService) 新建一个interface接口.改接口就是相当于webservice中的SEI. (在接口类定义前使用JDK自带webservice注释[email protected] SEI方法则是使用@WebMethod生命方法.) (2)在定

构建基于CXF的WebService服务(3)-- 利用拦截器实现权限验证

CXF中的拦截器分为in拦截器和out拦截器,又有客户端拦截器和服务端拦截器. 拦截器使用流程:客户端(out)-> 服务端(in)->处理业务->服务端(out)->客户端(in),并不是每一步都需要拦截器.在这里我们用到的是客户端Out拦截器和服务端in拦截器.服务端in拦截器检查用户级权限,客户端out浏览器发送用户信息给服务端. 1.创建服务端验证 JaxWsServerFactoryBean或Endpoint都可以通过getInInterceptors方法,向WebSer

【WebService】CXF拦截器的设置以及自定义CXF拦截器

WebService系列文章: [WebService]带你走进webservice的世界 [WebService]自定义WebService服务及其调用 [WebService]wsdl配置详解以及使用注解修改wsdl配置 [WebService]CXF处理javaBean等复合类型以及Map等复杂类型的数据 CXF的拦截器和以前学过的servlet的拦截器类似的,都是在开始或结束切入一段代码,执行一些逻辑之类的.我们可以在调用ws服务前设置拦截器,也可以在调用ws服务后设置拦截器,当然了,拦