CXF 框架拦截器

CXF的拦截器

•为什么设计拦截器?
1.为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
•拦截器分类:
1.按所处的位置分:服务器端拦截器,客户端拦截器
2.按消息的方向分:入拦截器,出拦截器
3.按定义者分:系统拦截器,自定义拦截器

•拦截器API
Interceptor(拦截器接口)
AbstractPhaseInterceptor(自定义拦截器从此继承)
LoggingInInterceptor(系统日志入拦截器类)
LoggingOutInterceptor(系统日志出拦截器类)


①系统拦截器
服务器端拦截器:

//通过终端类将helloWS对象发布到address上
                EndpointImpl endpoint = (EndpointImpl) Endpoint.publish(address, helloWS);
                //在服务器端添加一个日志的in拦截器
                endpoint.getInInterceptors().add(new LoggingInInterceptor());
                //在服务器端添加一个日志的out拦截器
                endpoint.getOutInterceptors().add(new LoggingOutInterceptor());

客户端拦截器:

//创建生成SEI实现对象的工厂
                HelloWSImplService factory = new HelloWSImplService();
                //得到web service的SEI的实现类对象(动态生成的对象)
                HelloWS helloWS = factory.getHelloWSImplPort();
                //得到客户端对象
                Client client = ClientProxy.getClient(helloWS);
                //添加客户端的out拦截器
                client.getOutInterceptors().add(new LoggingOutInterceptor());
                //添加客户端的in拦截器
                client.getInInterceptors().add(new LoggingInInterceptor());
                String result=helloWS.sayHello("tom")

②自定义拦截器
AbstractPhaseInterceptor:抽象过程拦截器,一般自定义的拦截器都会继承于它
功能:通过自定义拦截器实现用户名和密码的检查
1. 客户端:
设置out拦截器,向soap消息中添加用户名和密码数据

public class AddUserIntercept extends AbstractPhaseInterceptor<SoapMessage> {
                        private String name;
                        private String password;

                        public AddUserIntercept(String name, String pasword) {
                            super(Phase.PRE_PROTOCOL);
                            this.name = name;
                            this.password = pasword;

                        }

                        @Override
                        public void handleMessage(SoapMessage msg) throws Fault {
                            System.out.println("-----handleMessage");
                            Document document = DOMUtils.createDocument();
                            //<atguigu>
                            Element tgfile= document.createElement("tg");
                            //<name>tg</name>
                            Element nameEle = document.createElement("name");
                            nameEle.setTextContent(name);

                            //<password>123</password>
                            Element passwordEle = document.createElement("password");
                            passwordEle.setTextContent(password);

                    tgfile.appendChild(nameEle);
                            tgfile.appendChild(passwordEle);

                            //添加为请求消息的 头消息<soap:Header>  soap 有head ,body等  
                            msg.getHeaders().add(new Header(new QName("tg"), tgfile));
                        }

                    }
  1. 服务器端:
    设置in拦截器,从soap消息中获取用户名和密码数据,如果不满足条件就不执行web service的方法
public class MyIntercept extends AbstractPhaseInterceptor<SoapMessage> {
                        public MyIntercept() {
                            super(Phase.PRE_PROTOCOL);
                        }
                        @Override
                        public void handleMessage(SoapMessage msg) throws Fault {
                            System.out.println("-----handleMessage");

                            Header header = msg.getHeader(new QName("tg"));
                            if(header==null) {
                                System.out.println("没有通过拦截器");
                                throw new Fault(new RuntimeException("用户名密码不存在 "));
                            } else {
                                Element data = (Element) header.getObject();
                                if(data==null) {
                                    throw new Fault(new RuntimeException("用户名密码不存在22"));
                                } else {
                                    String name = data.getElementsByTagName("name").item(0).getTextContent();
                                    String password = data.getElementsByTagName("password").item(0).getTextContent();
                                    if(!"tg".equals(name) || !"123".equals(password)) {
                                        throw new Fault(new RuntimeException("用户名密码不正确"));
                                    }
                                }
                            }
                            System.out.println("通过拦截器了!");
                        }
                    }

  1. 说明:用户名和密码是以xml片断的形式存放在soap消息中的
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                        <soap:Header>
                            <tg>
                                <name>tanggao</name>
                                <password>123</password>
                            </tg>
                        </soap:Header>
                        <soap:Body>
                            <ns2:getStudentById xmlns:ns2="http://server.ws.java.tg.net/">
                                <arg0>1</arg0>
                            </ns2:getStudentById>
                        </soap:Body>
                    </soap:Envelope>
上一篇:开发复杂业务系统,有哪些设计思路


下一篇:2020年Java架构师必读书籍