文档章节

添加一个服务器端SOAP Handler

柳哥
 柳哥
发布于 2014/05/05 22:06
字数 624
阅读 1154
收藏 2

我们接着以前面的blog【HelloWord例子:客户端向请求SOAP消息中注入报头块(使用配置方式)】为例。在该例子基础上添加服务端的Handler,用来验证UUID值。

为了使例子更完整,我们需要一个服务端的SOAP Handler来处理客户端向出站SOAP消息中插入的报头块。我们来看看服务端都有什么变化。

HelloWord.java:

package ch03.ts;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Holder;

@WebService
public interface HelloWord {

    @WebMethod
    void sayHello(@WebParam(name="name") String name,
            @WebParam(name="wh",mode=WebParam.Mode.INOUT) Holder<String> wh,
            @WebParam(name="hf",mode=WebParam.Mode.OUT) Holder<String> hf);
}

HelloWordImpl.java(注意:这里添加了@HandlerChain(file="handler-chain-server.xml")注解,也就是服务器端的注解是添加在SIB上的):

package ch03.ts;

import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.xml.ws.Holder;

@WebService(endpointInterface = "ch03.ts.HelloWord")
@HandlerChain(file = "handler-chain-server.xml")
public class HelloWordImpl implements HelloWord {

    @Override
    public void sayHello(String name, Holder<String> wh, Holder<String> hf) {
        System.out.println(name + "!" + wh.value);
        wh.value = "你们好";
        hf.value = "同学们";
    }
}

HelloWordPublisher.java:

package ch03.ts;

import javax.xml.ws.Endpoint;

public class HelloWordPublisher {
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:7654/ts", new HelloWordImpl());
    }
}

新增加的服务器端Handler:UUIDValidator.java

package fibC;

import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
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;
import javax.xml.ws.soap.SOAPFaultException;

/**
 * 服务器端验证UUID值
 * @author fuhd
 */
public class UUIDValidator implements SOAPHandler<SOAPMessageContext> {
    
    private static final int UUIDVARIANT = 2;    //layout
    private static final int UUIDVERSION = 4;    //version

    @SuppressWarnings({ "rawtypes"})
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean resp = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if(!resp){
            try {
                SOAPMessage msg = context.getMessage();
                SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
                SOAPHeader hdr = env.getHeader();
                if(hdr == null)
                    generateSOAPFault(msg, "No message header.");
                Iterator it = hdr.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);
                if(it == null || !it.hasNext())
                    generateSOAPFault(msg, "No header block for next actor.");
                Node next = (Node)it.next();
                String value = (next == null)?null:next.getValue();
                if(value == null)
                    generateSOAPFault(msg, "No UUID in header block.");
                UUID uuid = UUID.fromString(value.trim());
                if(uuid.variant() != UUIDVARIANT || uuid.version() != UUIDVERSION)
                    generateSOAPFault(msg, "Bad UUID variant or version");
                System.out.println(value.trim());
            } catch (SOAPException e) {
                e.printStackTrace();
            } 
        }
        return true;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public void close(MessageContext context) {}

    @Override
    public Set<QName> getHeaders() {
        return null;
    }
    
    private void generateSOAPFault(SOAPMessage msg,String reason){
        try {
            SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
            SOAPFault fault = body.addFault();
            fault.setFaultString(reason);
            throw new SOAPFaultException(fault);
        } catch (SOAPException e) {
            e.printStackTrace();
        }
    }
}

handler-chain-server.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>fibC.UUIDValidator</javaee:handler-class>
        </javaee:handler>
    </javaee:handler-chain>        
</javaee:handler-chains>

UUIDValidator在服务层校验入站的SOAP消息。这个校验器需要访问整个SOAP消息,而不仅仅是SOAP消息体,因此它必须实现SOAPHandler接口,而不是一个LogicalHandler接口。

注意,上例中任何一部分校验失败均会抛出一个SOAPFaultException异常,重新包装为SOAP1.1和SOAP1.2错误。通过对错误的重新包装,我们可以忽略SOAP两个不同版本之间的差异。

© 著作权归作者所有

柳哥
粉丝 207
博文 405
码字总数 347782
作品 0
杭州
技术主管
私信 提问
JAX WS服务器端简介

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

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

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

晨曦之光
2012/04/25
834
0
为客户端添加拥有业务逻辑的Handler

以HelloWord为例,客户端的LogicalHandler可以拦截出站的请求消息以检查调用sayHello服务操作的输入参数。如果参数name值为“老板”则修改为“刘诗诗”。示例如下: 服务端: HelloWord.java...

柳哥
2014/05/05
481
0
php中soap使用,SoapServer服务端编写,SoapClient客户端编写

一,首先要设置服务器环境。 修改php.ini 得添加extension=phpsoap.dll (加载soap 内置包) 修改soap.wsdlcacheenabled=1 改为soap.wsdlcache_enabled=0 这个是soap的缓存,测试的时候最好改为...

JK_OPERA
2018/07/03
418
0
使用CXF Interceptor特性

在Web Service中,客户端和服务端通过交换信息来互相通信。信息在客户端组装,在服务端解组。在Web Service术语中,组装表示将JAVA对象转换为XML文件,这些XML文档将被传输到网络中;反而言之...

核桃白果
2013/08/06
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

移动开发中的 Web:WebView、WebKit、JSCore、Web 优化、热修复、跨平台、Native、Hybrid……

移动开发领域近年来已经逐渐告别了野蛮生长的时期,进入了相对成熟的时代。而一直以来 Native 和 Web 的争论从未停止,通过开发者孜孜不倦的努力,Web 的效率和 Native 的体验也一直在寻求着...

编辑部的故事
18分钟前
11
0
MySQL8.0.17 - Multi-Valued Indexes 简述

本文主要简单介绍下8.0.17新引入的功能multi-valued index, 顾名思义,索引上对于同一个Primary key, 可以建立多个二级索引项,实际上已经对array类型的基础功能做了支持 (感觉官方未来一定...

阿里云官方博客
今天
10
0
make4.1降级 make-3.81、2错误

在编译 make-3.82 的时候出现如下错误提示 glob/glob.c:xxx: undefined reference to `__alloca'` 修改 /glob/glob.c // #if !defined __alloca && !defined __GNU_LIBRARY__ # ifdef __GNUC......

Domineering
今天
16
0
Rainbond集群的安装和运维的原理

本文将解读Rainbond集群的安装和运维的原理,使用户基本了解Rainbond的安装机制和运维重点,便于用户搭建大型Rainbond集群。 1.Rainbond集群节点概述 1.1 节点分类 属性 类型 说明 manage 管...

好雨云帮
今天
10
0
好程序员大数据学习路线分享UDF函数

1.为什么需要UDF? 1)、因为内部函数没法满足需求。 2)、hive它本身就是一个灵活框架,允许用自定义模块功能,如可以自定义UDF、serde、输入输出等。 2.UDF是什么? UDF:user difine fun...

好程序员官方
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部