WebService开发 - CXF(6) -自定义拦截器(重点)

让人想犯罪 __ 提交于 2019-12-02 12:08:01

博主个人教程地址

前言

这篇说的是 自定义拦截器 通过自定义拦截器我们可以实现一些自定义的需求 还是非常灵活的

Server端代码

我们还是首先通过 getInInterceptors 来设置拦截器

在咱们的服务端代码中加入如下一行 这里的MyInterceptors是咱们自己需要创建的拦截器

jaxWsServerFactoryBean.getInInterceptors().add(new MyInterceptors());

拦截器类的内容 这里做的是一个比较简单认证 在我们的Soap消息中获取头部标签内的内容 因为是XML传输的吗 所以这里使用的XML的解析方式进行对应的解析 接受一个uname和pwd的参数这个参数是我们在客户端传递的 如果不匹配我们就抛出对应的错误 如果完全匹配 那么久通过拦截器的认证

同时我们是需要继承AbstractPhaseInterceptor类泛型为SoapMessage

super(Phase.PRE_INVOKE); 这句话的意思就是在之前调用的意思


public class MyInterceptors extends AbstractPhaseInterceptor<SoapMessage> {


    public MyInterceptors() {
        super(Phase.PRE_INVOKE);
    }



    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headers = message.getHeaders(); //根据soap消息获取头部
        if(headers == null && headers.size() == 0) {
            throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"));
        }
        Header firstHeader = headers.get(0); //我们等会只传一个头部过来
        Element elm = (Element) firstHeader.getObject();//将该头部转成一个Element对象
        NodeList userList = elm.getElementsByTagName("uname"); //根据标签获取值
        NodeList pwdList = elm.getElementsByTagName("pwd");

        // 进行身份认证
        if(userList.getLength() != 1) {//只有一个用户
            System.out.println("uname format error !");
            throw new Fault(new IllegalArgumentException("用户名格式不对"));
        }
        if(pwdList.getLength() != 1) {//只有一个密码
            System.out.println("pwd format error !");
            throw new Fault(new IllegalArgumentException("密码格式不对"));
        }
        String username = userList.item(0).getTextContent(); //因为就一个,所以获取第一个即可
        String  password= pwdList.item(0).getTextContent();

        if(!username.equals("lwx") || !password.equals("123456")) {
            System.out.println("username or password  error !");
            throw new Fault(new IllegalArgumentException("用户名或者密码错误"));
        }
    }

}

这里的话咱们的服务端代码就结束了

Client 端代码

下来修改客户端代码 其实差不多

也是需要首先要添加一个拦截器 只不过是再出的时候添加的

这里的构造器内的参数是我们需要传递过去认证的啦

client.getOutInterceptors().add(new MyInterpator("lwx", "123456"));

对应的还是 创建一个MyInterpator 类继承AbstractPhaseInterceptor类泛型为SoapMessage

在内部重写需要的方法 获取到 对应的 头部 然后在创建对应的元素添加到我们的头部中 携带到服务端 服务端获取之后进行认证即可

super(Phase.PREPARE_SEND); 这是在准备发送我们的消息的时候调用的拦截器


public class MyInterpator extends AbstractPhaseInterceptor<SoapMessage> {

    private String username;
    private String password;

    public MyInterpator(String username, String password) {
        super(Phase.PREPARE_SEND); //准备发送soap消息的时候调用拦截器
        this.username = username;
        this.password = password;
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List<Header> headerList = soapMessage.getHeaders();
        Document doc = DOMUtils.createDocument();

        // 定义三个对象
        Element elm = doc.createElement("authenticationHeader");
        Element userElm = doc.createElement("uname");
        Element pwdElm = doc.createElement("pwd");

        // 给用户名和密码对象赋值
        userElm.setTextContent(username);
        pwdElm.setTextContent(password);

        // 将用户名和密码的对象添加到elm中
        elm.appendChild(userElm);
        elm.appendChild(pwdElm);

        headerList.add(new Header(new QName("head"), elm));//往soap消息头部中添加这个elm元素
    }
}

之后我们进行客户端的启动 调用服务端程序 如果你传入的uname和pwd不符合服务端要求 那么就会跑出对应的错误 我们可以通过看控制台就可以得出结果 对应的日志也是可以的

从下面的日志中可以看出我们的authenticationHeader中包含了咱们的uname和pwd

Inbound Message
----------------------------
ID: 3
Address: http://localhost/helloworld
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[287], content-type=[text/xml; charset=UTF-8], Host=[localhost], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache-CXF/3.3.3]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><authenticationHeader><uname>lwx</uname><pwd>123456</pwd></authenticationHeader></soap:Header><soap:Body><ns2:getAllUserRole xmlns:ns2="http://service.server.liwenxiang.top/"/></soap:Body></soap:Envelope>
--------------------------------------

一切正常的话咱们的返回时就会是如下了吧 这里还是参考咱们上一届的代码哦 不要迷惑这里 如要你的没有报错就万事大吉

Programmer,1

结语

下一篇就开始来说如何与Spring整合使用 ~

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!