Apache CXF学习 - SOAP Handler的运用51CTO博客 - 千亿集团

Apache CXF学习 - SOAP Handler的运用51CTO博客

2019-01-03 13:58:30 | 作者: 冷霜 | 标签: 音讯,咱们,完结 | 浏览: 2165

引进:

咱们现已用前2篇的文章用2种办法创建了web service的endpoint而且对外供给效劳。现在咱们假定要对交游的音讯进行处理,而这些处理应该和咱们事务代码正交(也便是AOP,比方咱们要吧音讯写入日志,或许区别是去web service站点的恳求音讯仍是从web service站点回来的相应音讯),为了满意这个需求,咱们能够运用SOAPHandler来完结。


代码实践:

简略来说,SOAPHandler便是用来关于SOAP音讯进行处理的类,为了完结AOP,咱们有两种办法来完结对SOAP音讯的处理。

一种是完结SOAPHandler<SOAPMessageContext>接口,它会关于整个SOAP音讯进行处理。

一种是完结LogicalHandler<LogicalMessageContext>接口,它会对音讯的payload 进行处理。

咱们就别离写2个处理器,来演示这2种用法。


效劳器端:

首要,咱们开发一个LogHandler,它会阻拦交互的SOAP音讯而且打印出音讯内容,咱们让其选用第一种办法,完结SOAPHandler<SOAPMessageContext>接口:

/**
 * SOAP Handler能够用来对SOAP音讯进行拜访。
 * 有2种Handler,一种是拜访整个音讯的, 一种是只拜访SOAP音讯payload的
 * 这儿演示的是第一种,它有必要完结SOAPHandler<SOAPMessageContext>接口
 */
package com.charles.cxfstudy.server.handlers;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
/**
 * 演示拜访整个SOAP音讯的Handler的用法
 * @author charles.wang
 *
 */
public class LogHandler implements SOAPHandler<SOAPMessageContext>{
    /**
     * 怎么去处理SOAP音讯的逻辑。
     * 这儿会先打印当时调用的办法,然后从音讯上下文中取出音讯,然后写到规范输出流
     */
    public boolean handleMessage(SOAPMessageContext context) {
        System.out.println("LogHandler->handleMessage(context) method invoked");
        SOAPMessage message = context.getMessage();
        try{
            message.writeTo(System.out);
            System.out.println();
        }catch(Exception ex){
            System.err.print("Exception occured when handling message");
        }
        return true;
    }
    /**
     * 怎么去处理过错的SOAP音讯
     * 这儿会先打印当时调用的办法,然后从音讯上下文中取出音讯,然后写到规范输出流
     */
    public boolean handleFault(SOAPMessageContext context) {
        System.out.println("LogHandler->handleFault(context) method invoked");
        SOAPMessage message = context.getMessage();
        try{
            message.writeTo(System.out);
            System.out.println();
        }catch(Exception ex){
            System.err.print("Exception occured when handling fault message");
        }
        return true;
    }
    /**
     * 这儿没有资源整理的需求,所以咱们只打印动作到控制台
     */
    public void close(MessageContext context) {
        System.out.println("LogHandler->close(context) method invoked");
                                                                                                                                                                                                                                                                                                                                                                                   
    }
    public Set<QName> getHeaders() {
        return null;
    }
                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                               
}


然后咱们再开发AddCustomizedPartHandler,这个Handler会判别这个音讯是入站(往web service Endpoint发送的恳求音讯)音讯仍是出站(从web service Endpoint回来的音讯)音讯然后打印出成果,咱们选用第二种办法,让其完结 LogicalHandler<LogicalMessageContext>接口:

/**
 * SOAP Handler能够用来对SOAP音讯进行拜访。
 * 有2种Handler,一种是拜访整个音讯的, 一种是只拜访SOAP音讯payload的
 * 这儿演示的是第二种,它有必要完结LogicalHandler<LogicalMessageContext>接口
 */
package com.charles.cxfstudy.server.handlers;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.handler.MessageContext;
/**
 * 演示拜访SOAP音讯的payload的Handler的用法
 * @author charles.wang
 *
 */
public class AddCustomizedPartHandler implements LogicalHandler<LogicalMessageContext> {
    /**
     * 怎么去处理SOAP音讯的逻辑,它会去判别这是入站仍是出站音讯
     */
    public boolean handleMessage(LogicalMessageContext context) {
        System.out.println("AddCustomizedPartHandler->handleMessage(context) invoked");
                                                                                                                                                                                                                                                                                                                      
        //先判别音讯来源是入站仍是出站的
        //(入站表明是发送到web service站点的音讯,出站表明是从web service站点回来的音讯)
        boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
                                                                                                                                                                                                                                                                                                                      
        //如果是出站音讯
        if(outbound){
            System.out.println("This is an outbound message");     
        }else{
            System.out.println("This is an inbound message");
        }
                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                      
        return true;
    }
    public boolean handleFault(LogicalMessageContext context) {
        System.out.println("AddCustomizedPartHandler->handleFault(context) invoked");
        return true;
    }
    public void close(MessageContext context) {
        System.out.println("AddCustomizedPartHandler->close(context) invoked");
                                                                                                                                                                                                                                                                                                                      
    }
                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                  
}



为了让这2个handler收效,咱们有必要写一个装备文件,来装备处理器链,这儿咱们自界说某个handler_chains.xml(能够是恣意姓名),而且在其间装备了2个处理器,界说他们的次序和完结类:

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
   <handler-chain>
    <handler>
        <handler-name>AddCustomizedPartHandler</handler-name>
        <handler-class>com.charles.cxfstudy.server.handlers.AddCustomizedPartHandler</handler-class>
    </handler>
    <handler> 
        <handler-name>LogHandler</handler-name>
        <handler-class>com.charles.cxfstudy.server.handlers.LogHandler</handler-class>
    </handler>
   </handler-chain>
</handler-chains>

从这儿看出,判别入站出站的处理器在前,打印日志的处理器在后。


为了让咱们的Handler链收效到咱们的web service的Endpoint,咱们有必要在效劳接口或许效劳完结类上用@HandlerChain注解来装备这个Handler链界说文件。这儿,咱们为前面开发的加法运算的web效劳激活处理器,所以在CalcServiceImpl上咱们选用了这个注解:

@WebService(endpointInterface="com.charles.cxfstudy.server.services.ICalcService")
//这儿展现怎么用@HandlerChain来声明一组Handler,他们会对指定的web service运用的SOAP音讯进行处理,类似AOP
@HandlerChain(file="/handler_chains.xml")
public class CalcServiceImpl implements ICalcService {
...


这时候,打包使用而且布置在效劳器上,咱们效劳器端的代码就完结了。


客户端:

为了演示客户端和效劳器端的交互是否会主动触发Handler的履行,咱们写一个客户端,首要咱们用JDK的wsimport东西来从给定的wsdl文件生成一组客户端的java文件:


这样它会在咱们给定目选用给定的包名生成一组文件:

咱们把这些文件复制到咱们客户端的项目使用中,然后编写测验办法如下:

/**
 * 客户端测验代码
 */
package com.charles.cxfclient;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
/**
 * @author charles.wang
 *
 */
public class MainTest {
                                                                                                                                                             
    public static void main(String [] args){
                                                                                                                                                             
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setServiceClass(ICalcService.class);
    factory.setAddress("http://localhost:8080/cxf_jaxws_server/services/calc");
                                                                                                                                                             
    //调用事务办法
    ICalcService service = (ICalcService) factory.create();
    int a = 3,b=5;
    System.out.println("调用CalcService进行加法核算,2个运算子别离是:"+a+","+b);
    System.out.println("加法运算成果为:" + service.calcSum(a, b));
                                                                                                                                                             
    }
}


履行,它明显会打印出履行成果,不过这个履行的成果运算是经过 web service的调用完结的。


咱们来看效劳器的日志,如下图:

明显,这两个Handler都被正确的调用了(能够比较咱们的Handler的代码),比方AddCustomizedPartHandler会正确的辨认这是inbound 仍是outbound音讯,比方LogHandler能吧inbound音讯(便是图片中内含<a>3</a><b>5</b>的)和outbound音讯(便是图片中内在<return>8</return>的)都打印出来,所以证明咱们开发的Handler是正确的。


当然了,Handler还能够做许多更高等级的功用,比方查验cookie,耐久化音讯,增加自界说头号,有待咱们发觉,可是代码的结构大体和咱们比如类似。

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表千亿集团立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章