cxf有一些内置的拦截器,先熟悉一下cxf添加拦截器的流程。
package com.bxw.test; 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.bxw.service.Service; import com.bxw.service.impl.ServiceImpl; public class Test { public static void main(String[] args) { System.out.println("web service start"); Service implementor = new ServiceImpl(); String address = "http://localhost:9095/helloWorld"; // Endpoint.publish(address, implementor); // JDK实现 JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.setAddress(address); // 设置暴露地址 factoryBean.setServiceClass(Service.class); // 接口类 factoryBean.setServiceBean(implementor); // 设置实现类 factoryBean.getInInterceptors().add(new LoggingInInterceptor());//添加in日志信息 factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());//添加out日志信息 factoryBean.create(); } }
服务端添加拦截器:
factoryBean.getInInterceptors().add(new LoggingInInterceptor());//添加in日志信息.
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());//添加out日志信息.
客户端是无法直接添加拦截器的,需要先用代理获得一个客户端:
package com.bxw.test; import java.util.List; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import com.bxw.ws.MyRole; import com.bxw.ws.Role; import com.bxw.ws.Service; import com.bxw.ws.ServiceService; public class ClientTest { public static void main(String[] args) { ServiceService ss = new ServiceService(); Service port = ss.getServicePort(); //客户端添加拦截器 Client client = ClientProxy.getClient(port); client.getInInterceptors().add(new LoggingInInterceptor()); client.getInInterceptors().add(new LoggingOutInterceptor()); List<MyRole> roles = port.getRoles().getItem(); for(MyRole r:roles){ List<Role> ls = r.getValue(); for(Role role:ls){ System.out.println("id:"+role.getId()+" "+"rolename:"+role.getRoleName()); } } } }
自定义拦截器:
使用拦截器进行权限的认证。自定义拦截器需要继承AbstractPhaseInterceptor<SoapMessage>
,其中SoapMessage是用来封装soap消息:服务端:
发布时添加拦截器:
factoryBean.getInInterceptors().add(new MyInterceptor());
自定义拦截器:
package com.bxw.entity; 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; public class MyIntercepter extends AbstractPhaseInterceptor<SoapMessage>{ public MyIntercepter() { super(Phase.PRE_INVOKE); //调用之前先调用拦截器 } public void handleMessage(SoapMessage message) throws Fault { List<Header> headers = message.getHeaders(); if(headers==null || headers.size()==0){ throw new Fault(new IllegalArgumentException("没有headers,拦截器拦截")); } Header header = headers.get(0); Element elem = (Element) header.getObject(); NodeList userList = elem.getElementsByTagName("user"); NodeList pwdList = elem.getElementsByTagName("password"); //身份验证 if(userList.getLength()!=1){ throw new Fault(new IllegalArgumentException("用户名格式不对")); } if(pwdList.getLength()!=1){ throw new Fault(new IllegalArgumentException("密码格式不对")); } String username = userList.item(0).getTextContent(); String password = pwdList.item(0).getTextContent(); if(!("admin".equals( username)) || !("123".equals(password))){ throw new IllegalArgumentException("用户名或密码错误"); } } }
客户端访问服务时会传过来一个soap消息,我们会将用户名和密码封装到头部中传过来,通过解析soap消息中头部的数据,来进行身份认证。
客户端访问服务端前添加拦截器:
client.getOutInterceptors().add(new AddHeaderInterceptor("admin", "123"));//添加自定义拦截器
自定义拦截器:
package com.bxw.entity; 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 AddHeaderIntercepter extends AbstractPhaseInterceptor<SoapMessage>{ private String username; private String password; public AddHeaderIntercepter(String name,String password) { super(Phase.PREPARE_SEND); this.username = name; this.password = password; } public void handleMessage(SoapMessage message) throws Fault { List<Header> headers = message.getHeaders(); Document doc = DOMUtils.createDocument(); //定义三个对象 Element elem = doc.createElement("authHeader"); Element userElem = doc.createElement("user"); Element passElem = doc.createElement("password"); userElem.setTextContent(username); passElem.setTextContent(password); elem.appendChild(userElem); elem.appendChild(passElem); headers.add(new Header(new QName("head"), elem)); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
首先通过构造函数将用户名和密码传进去,然后获取将要发送的soap消息的头部,紧接着人为构造出几个元素,将用户名和密码封装到元素中去,并放到soap消息的头部,这样soap消息就会携带这个用户名和密码的消息了
时间: 2024-10-11 12:20:15