前面咱們說到CXF添加內置的攔截器,今天的話,咱們來說下如何添加自定義攔截器;java
咱們的實例是客戶端訪問服務端webservice接口要加權限認證。web
咱們思路先說下。咱們能夠經過在SOAP消息的Header頭信息中添加自定義信息,而後發送到服務端端,服務器端經過獲取apache
Header頭消息,而後進行認證;這裏的添加消息,和獲取消息認證,咱們都是經過自定義攔截器來實現;服務器
OK下面咱們來實現下:app
首先是服務器端:frontend
咱們自定義攔截器:MyInterceptordom
package com.wishwzp.interceptor; 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; /** * 自定義攔截器 * @author Administrator * */ public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public MyInterceptor() { // 在調用方法以前調用攔截器 super(Phase.PRE_INVOKE); } /** * 攔截獲取消息 */ @SuppressWarnings("null") public void handleMessage(SoapMessage message) throws Fault { List<Header> headers=message.getHeaders(); if(headers==null && headers.size()==0){ throw new Fault(new IllegalArgumentException("沒有Header,攔截器實施攔截")); } Header firstHeader=headers.get(0); Element ele=(Element) firstHeader.getObject(); NodeList uList=ele.getElementsByTagName("userName"); NodeList pList=ele.getElementsByTagName("password"); if(uList.getLength()!=1){ throw new Fault(new IllegalArgumentException("用戶名格式不對")); } if(pList.getLength()!=1){ throw new Fault(new IllegalArgumentException("密碼格式不對")); } String userName=uList.item(0).getTextContent(); String password=pList.item(0).getTextContent(); if(!userName.equals("wishwzp")||!password.equals("123456")){ throw new Fault(new IllegalArgumentException("用戶名或者密碼不正確")); } } }
這裏的話,咱們主要是獲取Header頭消息,而後獲取userName和password節點,而後獲取值,進行權限判斷,假如認證不經過,咱們拋出異常;測試
在Server類裏,咱們要添加一個in 攔截器,在進入的時候,咱們要進行驗證;this
package com.wishwzp.webservice; 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.wishwzp.interceptor.MyInterceptor; import com.wishwzp.webservice.impl.HelloWorldImpl; public class Server { public static void main(String[] args) { System.out.println("web service start"); HelloWorld implementor = new HelloWorldImpl(); String address = "http://192.168.0.110/helloWorld"; //Endpoint.publish(address, implementor); // JDK實現 暴露webservice接口 JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.setAddress(address); // 設置暴露地址 factoryBean.setServiceClass(HelloWorld.class); // 接口類 factoryBean.setServiceBean(implementor); // 設置實現類 factoryBean.getInInterceptors().add(new LoggingInInterceptor()); // 添加in攔截器 日誌攔截器 factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out攔截器 factoryBean.getInInterceptors().add(new MyInterceptor()); // 添加自定義攔截器 factoryBean.create(); System.out.println("web service started"); } }
接下來是修改客戶端代碼:spa
咱們一樣要添加一個自定義攔截器:AddHeaderInterceptor
package com.wishwzp.interceptor; 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 AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String userName; private String password; public AddHeaderInterceptor(String userName,String password) { super(Phase.PREPARE_SEND); // 發送SOAP消息以前調用攔截器 this.userName=userName; this.password=password; } public void handleMessage(SoapMessage message) throws Fault { List<Header> headerList=message.getHeaders(); Document doc=DOMUtils.createDocument(); Element ele=doc.createElement("authHeader"); Element uElement=doc.createElement("userName"); uElement.setTextContent(userName); Element pElement=doc.createElement("password"); pElement.setTextContent(password); ele.appendChild(uElement); ele.appendChild(pElement); headerList.add(new Header(new QName("wishwzp"),ele)); } }
這裏的話,咱們主要是在攔截器裏建立頭消息;
Client類裏咱們要修改下,加下Out 攔截器:
package com.wishwzp.webservice; import java.util.List; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import com.wishwzp.interceptor.AddHeaderInterceptor; public class Client { public static void main(String[] args) { HelloWorldService service=new HelloWorldService(); HelloWorld helloWorld=service.getHelloWorldPort(); org.apache.cxf.endpoint.Client client=ClientProxy.getClient(helloWorld); //client.getInInterceptors().add(new LoggingInInterceptor()); // 添加in攔截器 日誌攔截器 client.getOutInterceptors().add(new AddHeaderInterceptor("wishwzp","123")); // 添加自定義攔截器 client.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out攔截器 //System.out.println(helloWorld.say("wishwzp測試")); // User user=new User(); // user.setUserName("jack"); // user.setPassword("123456"); // List<Role> roleList=helloWorld.getRoleByUser(user); // for(Role role:roleList){ // System.out.println(role.getId()+","+role.getRoleName()); // } MyRoleArray array=helloWorld.getRoles(); List<MyRole> roleList=array.item; for(int i=0;i<roleList.size();i++){ MyRole my=roleList.get(i); System.out.print(my.key+":"); for(Role r:my.value){ System.out.print(r.getId()+","+r.getRoleName()+" "); } System.out.println(); } } }
OK這樣就完整了自定義攔截器實現權限認證;
先運行Server類,和之前同樣;
假如咱們把 client.getOutInterceptors().add(new AddHeaderInterceptor("wishwzp","123456")); // 添加自定義攔截器
密碼改爲 123
而後運行Client類,會報錯;
用戶名或者密碼不正確;