文档章节

JAX-WS使用Handler Chain加工消息

xpbug
 xpbug
发布于 2014/04/27 10:47
字数 1120
阅读 2391
收藏 4

承前

本文的示例,是基于前一篇文章中的实例而改进的,如果想要运行本文的代码例子,需要先实现前一篇的代码。

前一篇文章JAX-WS开发WebService初级 

Handler概念

在WebService目录下的上一篇文章中,给出来一个初级的WebService开发实例。接下来的几篇文章,将一步一步更加深入的讨论JAXWS中的各种特性。当我们了解JAXWS所有特性之时,就可以对WebService的开发了如指掌了。

Servlet肯定无人不知晓,在servlet中,存在着FilterChain。FilterChain由一串的Filter顺序排列组建而成,Filter可以在Resquest到达servlet之前,和Response离开servlet之后处理一些逻辑。在WebService中,我们可以使用Handler Chain。

在JAXWS下,存在两个Handler接口,LogicalHandler和SOAPHandler. LogicalHandler处理的是Message Payload, 而SOAPHandler则处理的是整个SOAP消息。注册Handler的方式有下面几种:

  1. 编程方式,使用handlerResolver。

  2. 使用Annotation javax.ws.HandlerChain来指向配置文件。

  3. 从WSDL生成。

  4. 使用custom binding声明HandlerChain。

  5. 在sun-jaxws.xml中声明。

执行顺序

像Servlet Filter一样,如果依次声明了H1,H2,H3,H4几个Handler,那么,对于进站的Message,则依次通过H1,H2,H3,H4,然后到Endpoint。对于出站的消息,则依次通过H4,H3,H2,H1. 所以,整个消息经过的路径应该是H1,H2,H3,H4,Endpoint,H4,H3,H2,H1.

如果同时声明了LogicalHandler和SOAPHandler,LogicalHandler要优先于SOAPHandler。LogicalHandler将提前。

每个Handler都有两个方法:handleMessage和handleFault. 它们的作用如下:

对于正常的message,在经过handlerchain的时候,会依次调用每个handler的handleMessage方法。

当在Endpoint执行之前,如果handleMessage返回false,则不再向后执行,返回message. 如果抛出异常,后面的handler则执行handleFault方法。如果handleFault返回true,则继续执行后面的handleFault。如果返回为false,则不再执行后面的handler,直接返回FaultMessage。

当在Endpoint执行完毕以后,如果handleMessage返回false,message方向调头,继续执行后面的Handler。如果抛出异常,后面的handler则执行handleFault方法。如果handleFault返回true,则继续执行后面的handleFault。如果返回为false,则不再执行后面的handler,直接返回FaultMessage。

LogicalHander

此Handler处理的是Message Payload,对author为空的均改为“xpbug”。

在上一篇文章,我们介绍了wsimport工具。wsimport可以根据wsdl文件生成相应的java文件。下面的handler也需要使用这些java类。下面用到的wsimport所生成的java类为ObjectFactory和AddRawBook.

public class AuthorHandler implements LogicalHandler<LogicalMessageContext> {

    public boolean handleMessage(LogicalMessageContext context) {
        boolean outBound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        //判断是出站消息还是进站消息。只对出站消息做修改
        if (outBound) {
            LogicalMessage message = context.getMessage();
            JAXBContext jaxbc=null;
            try {
                //ObjectFactory为wsimport根据wsdl所生成。
                jaxbc = JAXBContext.newInstance(ObjectFactory.class);
                Object obj = ((JAXBElement)message.getPayload(jaxbc)).getValue();
                //载体是不是AddRawBook
                //AddRawBook为wsimport根据wsdl所生成。
                if (obj instanceof AddRawBook) {
                    AddRawBook book = (AddRawBook) obj;
                    if ("".equals(book.getAuthor())) {
                        book.setAuthor("xpbug");
                        message.setPayload(new ObjectFactory().createAddRawBook(book), jaxbc);
                    }
                }
            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    public boolean handleFault(LogicalMessageContext context) {
        // TODO Auto-generated method stub
        return false;
    }

    public void close(MessageContext context) {
        // TODO Auto-generated method stub
    }
}

SOAPHandler

SOAPHandler处理的是SOAP整个消息,包含soap header和soap body。一般可以使用SOAPHandler来处理header,比如加入一些header。本文将实现一个handler,打印所有进出的soap message全文。

public class LoggerHandler implements SOAPHandler<SOAPMessageContext> {

    public boolean handleMessage(SOAPMessageContext context) {
        boolean outBound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outBound) {
            System.out.println("<<<<<<<<<<<<<<<<");
            System.out.println("Message out:");
        } else {
            System.out.println(">>>>>>>>>>>>>>>>");
            System.out.println("Message in:");
        }
        try {
            context.getMessage().writeTo(System.out);
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("");
        return true;
    }

    public boolean handleFault(SOAPMessageContext context) {
        // TODO Auto-generated method stub
        return false;
    }

    public void close(MessageContext context) {
        // TODO Auto-generated method stub
        
    }

    public Set<QName> getHeaders() {
        return null;
    }

}

配置Handlers

handler可以安装在server端,也可以安装在客户端。为了不改动server,我只修改客户端。

首先,书写handlers的配置文件,在maven project中,在main/resources/下面创建handler-chain.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains 
     xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>com.mycompany.library.AuthorHandler</javaee:handler-class>
    </javaee:handler>
    <javaee:handler>
      <javaee:handler-class>com.mycompany.library.LoggerHandler</javaee:handler-class>
    </javaee:handler>
  </javaee:handler-chain>
</javaee:handler-chains>

然后,修改LibraryService.java,此文件是由wsimport产生的。将hander配置文件注册在Webservice client上。

@WebServiceClient(name = "LibraryService", targetNamespace = "http://library.mycompany.com", wsdlLocation = "http://127.0.0.1:8080/library/service?wsdl")
@HandlerChain(file="handler-chain.xml")
public class LibraryService

运行客户端

修改App.java的main函数

public class App {
    public static void main( String[] args ) throws LibraryException_Exception {
        
        int id;
        String rawBook;
        id = createPort().addRawBook("java", "");
        rawBook = createPort().getRawBook(id);
        System.out.println("find"+rawBook);
    }
    
    public static Library createPort() {
        Library port = new LibraryService().getLibraryPort();
        return port;
    }
}

运行App,查看控制台的输出。

© 著作权归作者所有

xpbug
粉丝 304
博文 101
码字总数 124566
作品 0
浦东
程序员
私信 提问
JAX-WS Customization

介绍 在之前的文章中,有一篇关于HandlerChain的介绍。当时HandlerChain使用的是Java Annotation方式注册到WebService上的。我们也可以使用JAX-WS提供的针对WSDL的customization,来配置Han...

xpbug
2014/04/29
629
0
JAX WS服务器端简介

本文简单介绍JAX WS在服务器端是如何实现和运行的。 下面这幅图描述了一个SOAP binding的JAX WS从接受到客户端的请求到返回请求给客户端的过程。 1,客户端开发者通过URL得到WSDL文件。(通过H...

晨曦之光
2012/04/25
546
0
JAX-WS中通过Handler操作SOAP消息

在JAVA实现的Web service的客户端和服务器端都可以通过handler来实现对SOAP消息的访问,典型的应用可以用来保存SOAP消息(作为Log,或者在流程失败的时候重新发消息,或者操作SOAP header设定sec...

晨曦之光
2012/04/25
841
0
JAX-WS Provider和Dispatch

在之前的文章中,涉及到了WebService的搭建。所有的EndPoint均是高度面向对象,面向逻辑了。Server与Client之间交互的消息,均由JAXB转为JAVA类型。如果想对消息的原始数据进行修改,可以使用...

xpbug
2014/04/28
1K
0
Java的Web服务规范API--JAX-WS

JAX-WS (JavaTM API for XML-Based Web Services)规范是一组XML web services的JAVA API。JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。 在 JAX-WS......

匿名
2010/08/27
5.6K
1

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0
从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
7
0
程序性能checklist

程序性能checklist

Moks角木
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部