webService之攔截器

            聽到攔截器,其實我們就應該想到它的作用:即在我們每次訪問請求的時候都會被攔截,先去處理一些其它的事情。比如說在webService上,我們對發佈的服務有權限要求,只有有權限的纔可以訪問我們的服務。而在此處,其實現就要用到我們的攔截器了,具體如下:

服務端

1、添加攔截器類(用戶接受客戶端消息)

public class AuthInterceptor  extends AbstractPhaseInterceptor<SoapMessage>{
    public AuthInterceptor() {
        //super表示顯示調用父類有參數的構造器
        //顯示調用父類構造器,程序將不會隱式調用父類無參數的構造器
        super(Phase.PRE_INVOKE); //該攔截器將會“調用之前”攔截SOAP消息
    }
    //實現自己的攔截器時,需要實現handleMessage方法
    //handleMessage方法中的形參就是被攔截到的Soap消息
    //一旦程序獲取了SOAP消息,剩下的事情就可以解析SOA消息,或修改SOAP消息
    @Override
    public void handleMessage(SoapMessage msg) throws Fault {
        //從這裏可以看出,我們已經攔截到了SOAP消息
        System.out.println("-------------" +msg);
        
        //得到SOAP消息所有Header
        List<Header> headers=msg.getHeaders();
        
        //如果根本沒有Header
        if (headers==null || headers.size()<1){
            throw new Fault(new IllegalArgumentException("根本沒有Header,別笑調用!"));
        }
        
        //假如要求第一個Header攜帶 了用戶名、密碼信息
        Header firstHeader=headers.get(0);
        Element element=(Element)firstHeader.getObject();
        
        NodeList userIds=element.getElementsByTagName("userId");
        NodeList userPasses=element.getElementsByTagName("userPass");
        
        if (userIds.getLength() !=1){
            throw new Fault(new IllegalArgumentException("用戶名格式不對!"));
        }
        if (userPasses.getLength() !=1){
            throw new Fault(new IllegalArgumentException("密碼格式不對!"));
        }
        
        //獲取用戶名和密碼
        String userId=userIds.item(0).getTextContent();
        String userPass=userPasses.item(0).getTextContent();
        
        if (!userId.equals("lj") || !userPass.equals("lj")){
            throw new Fault(new IllegalArgumentException("用戶名或密碼不正確!"));
        }
    }
}
2、發佈webService的時候將攔截器配置上

public class ServerMain {
    public static void main(String[] args) throws IOException {
        HelloWorld hw=new HelloWorldWs();
        //調用Endpoint的publish方法發佈Web Service
        EndpointImpl ep= (EndpointImpl)Endpoint.publish("http://192.168.1.111:8088/HelloWorld", hw);
        
        //============第一種,將日誌以文件形式輸出=================================================
//        //添加In攔截器
//        ep.getInInterceptors().add(new LoggingInInterceptor(new PrintWriter(new FileWriter("in.txt"))));
//        //添加Out攔截器
//        ep.getOutInterceptors().add(new LoggingOutInterceptor(new PrintWriter(new FileWriter("out.txt"))));
        
        //=============第二種,將日誌輸出到控制檯=================================================
//        //添加In攔截器
//        ep.getInInterceptors().add(new LoggingInInterceptor());
//        //添加Out攔截器
//        ep.getOutInterceptors().add(new LoggingOutInterceptor());
                
        //===========第三種,自定義攔截器,此處添加的是上面的攔截器===============================
        ep.getInInterceptors().add(new AuthInterceptor());
        System.out.println("webService 發佈成功!");
    }
}

客戶端

1、添加攔截器類(用戶向webService傳遞消息):

public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
    private String userId;
    private String userPass;
    
    public AddHeaderInterceptor(String userId,String userPass) {
        //在準備發送soap消息時啓用該攔截器
        super(Phase.PREPARE_SEND);
        this.userId=userId;
        this.userPass=userPass;
    }
    @Override
    public void handleMessage(SoapMessage msg) throws Fault {
        List<Header> headers=msg.getHeaders();
        
        //創建Docuemnt對象
        Document document=DOMUtils.createDocument();
        Element element=document.createElement("authHeader");
        
        Element idElement=document.createElement("userId");
        idElement.setTextContent(userId);
        
        Element passElement=document.createElement("userPass");
        passElement.setTextContent(userPass);
        
        element.appendChild(idElement);
        element.appendChild(passElement);
        
        /**
         * 上面代碼生成了一個如下XML文檔片段
         * <authHeader>
         *         <userId>aaa</userId>
         *         <userPass>bbb</userPass>
         * </authHeader>
         */
        //把element元素包裝成Header,並添加到SOAP消息的Header列表中
        headers.add(new Header(new QName("lj"),element));
    }
}

 2、客戶端調用webService的時候添加此攔截器

public class ClientMain {
    public static void main(String[] args) {
                HelloWorld factory=new HelloWorld();
                com.tgb.web.webservice.HelloWorld hWorld= factory.getHelloWorldWsPort();

//        //客戶端調用日誌攔截器
//        Client client=ClientProxy.getClient(hWorld);
//        client.getInFaultInterceptors().add(new LoggingInInterceptor());
//        client.getInFaultInterceptors().add(new LoggingOutInterceptor());

                //客戶端調用攔截器
                Client client=ClientProxy.getClient(hWorld);
                client.getOutInterceptors().add(new AddHeaderInterceptor("lj","lj"));
                client.getOutInterceptors().add(new LoggingOutInterceptor());
                
                System.out.println(hWorld.sayHi("張三"));
                
                System.out.println("===================================================");
                
                User user=new User();
                user.setId(30);
                user.setName("sun");
                user.setPass("3322");
                
                List<Cat> cats=hWorld.getCatsByUser(user);
                for(Cat cat :cats){
                    System.out.println(cat.getName());
                }
                
                System.out.println("===================================================");
                
                //調用CXF處理過的類型方法
                StringCat SC=hWorld.getAllCats();
                for(Entry entry:SC.getEntries()){
                    System.out.println(entry.getKey()+"-"+entry.getValue().getName());
                }
    }
}

由此我們就可以實現我們的權限訪問功能了,是不是很強大啊!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章