Java网络服务: User defined meta-data

标签 java web-services jboss jax-ws

我在 Jboss 4.2.3 上实现了 SOAP Web 服务。我想为该服务添加版本号检查。每当客户端调用时,我都会传递客户端版本号。我将在服务器上编写一个拦截器来检查客户端版本号。如果是不同版本号的客户端,我不会处理该请求。

我想知道的是,除了将版本号添加到 Web 服务方法签名中之外,是否有其他方法可以在某些上下文参数中从客户端传递版本号?

一般来说,如果我想将一些自定义元数据从客户端传递到服务器,我该怎么做?

最佳答案

In general, if I want to pass some custom META-DATA from client to server, how do I do it ?

<小时/>

这可以通过SOAP Message Handlers来实现 Jax-WS 中的双方(客户端和服务器)。

客户端:

自定义元数据,如版本号、UUID、签名信息可以通过SOAP Headers添加.

1..编写一个VersionNumberHandler,如下所示。

public class VersionNumberHandler implements SOAPHandler<SOAPMessageContext> {
private static final String LoggerName = "ClientSideLogger";
private Logger logger;
private final boolean log_p = true; // set to false to turn off

public VersionNumberHandler() {
    logger = Logger.getLogger(LoggerName);
}

public boolean handleMessage(SOAPMessageContext ctx) {
    if (log_p)
        logger.info("handleMessage");

    // Is this an outbound message, i.e., a request?
    Boolean request_p = (Boolean) ctx
            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    // Manipulate the SOAP only if it's a request
    if (request_p) {
        // Get the Version Number from some property file ,
        // to place in the message header.
        String versionNumber = "v1.0";

        try {
            SOAPMessage msg = ctx.getMessage();
            SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
            SOAPHeader hdr = env.getHeader();
            // Ensure that the SOAP message has a header.
            if (hdr == null)
                hdr = env.addHeader();

            QName qname = new QName("http://ticket.example.com/",
                    "versionnumber");
            SOAPHeaderElement helem = hdr.addHeaderElement(qname);

            // In SOAP 1.2, setting the actor is equivalent to
            // setting the role.
            helem.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
            helem.setMustUnderstand(true);
            helem.addTextNode(versionNumber);
            msg.saveChanges();

            // For tracking, write to standard output.
            msg.writeTo(System.out);
        } catch (SOAPException e) {
            System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
        }
    }
    return true; // continue down the chain
}

public boolean handleFault(SOAPMessageContext ctx) {
    if (log_p)
        logger.info("handleFault");
    try {
        ctx.getMessage().writeTo(System.out);
    } catch (SOAPException e) {
        System.err.println(e);
    } catch (IOException e) {
        System.err.println(e);
    }
    return true;
}

public Set<QName> getHeaders() {
    if (log_p)
        logger.info("getHeaders");
    return null;
}

public void close(MessageContext messageContext) {
    if (log_p)
        logger.info("close");
}

2..在 Handler-Chain.xml 中提及此类。

<javaee:handler>
<javaee:handler-class>
com.example.client.handler.VersionNumberHandler
</javaee:handler-class>
</javaee:handler>

3..还在客户端( stub )中添加处理程序链。

@WebServiceClient(name = "TicketWSImplService", targetNamespace =    "http://ticket.example.com/", wsdlLocation = "http://localhost:8080/ticket?wsdl")
@HandlerChain(file = "handler-chain.xml")
public class TicketWSImplService extends Service {

@WebMethod
public void method(){

}

在这里,我们添加了一个新的 header 元素“versionnumber”并且mustunderstand=true,这意味着服务器/中介必须处理该元素,否则Jax-WS-Runtime将向客户端抛出SOAP错误异常。现在我们需要在服务器端编写一个 validator (SOAP Handler)来验证客户端传递的版本号。

服务器端:

1..编写一个VersionNumberValidator,如下所示。

public class VersionNumberValidator implements SOAPHandler<SOAPMessageContext> {
@SuppressWarnings("unused")
@Override
public boolean handleMessage(SOAPMessageContext ctx) {
    // Is this an inbound message, i.e., a request?
    Boolean response_p = (Boolean) ctx
            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    // Manipulate the SOAP only if it's incoming.
    if (!response_p) {
        try {
            SOAPMessage msg = ctx.getMessage();
            SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
            SOAPHeader hdr = env.getHeader();

            // Ensure that the SOAP message has a header.
            if (hdr == null) {
                generateSOAPFault(msg, "No message header.");
                return true;
            }

            Iterator mustUnderstandHeaders = msg.getSOAPHeader()
                    .examineMustUnderstandHeaderElements(
                            "http://schemas.xmlsoap.org/soap/actor/next");
            String value = null;
            while (mustUnderstandHeaders.hasNext()) {
                Node next = (Node) mustUnderstandHeaders.next();
                System.out.println("mustUnderstandHeaders name:"
                        + next.getValue());
                if (next.getNodeName().equalsIgnoreCase("versionnumber"))
                    value = next.getValue();
                if (value != null && !value.equalsIgnoreCase("v1.0")) {
                    generateSOAPFault(msg, "Version Number Mismatch");
                }
            }

            // For tracking, write to standard output.
            msg.writeTo(System.out);
        } catch (SOAPException e) {
            System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
        }
    }
    return true; // continue down the chain
}

@Override
public boolean handleFault(SOAPMessageContext ctx) {

    return true; // do continue down the chain
}

// For now, no-ops.
@Override
public Set<QName> getHeaders() {

    Set<QName> headers = new HashSet<QName>();
    QName qName = new QName("http://ticket.example.com/", "versionnumber");
    headers.add(qName);

    return headers;
}

@Override
public void close(MessageContext messageContext) {
}

private void generateSOAPFault(SOAPMessage msg, String reason) {
    try {
        SOAPBody body = msg.getSOAPBody();
        SOAPFault fault = body.addFault();
        QName fault_name = new QName(
                SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "UltimateReceiver");
        fault.setFaultCode(fault_name);
        fault.setFaultRole("http://ticket.example.com/versionNumber_validator");
        fault.addFaultReasonText(reason, Locale.US);
    } catch (SOAPException e) {
    }
}

2..在 Handler-Chain-server.xml 中提及此类。

<javaee:handler>
<javaee:handler-class>
com.example.client.handler.VersionNumberValidator
</javaee:handler-class>
</javaee:handler>

3..发布网络服务。

现在,每个客户端请求都会有“版本号=v1.0”,在服务器端,您将验证该值是否正确。如果不正确,将抛出 SOAPFaultException。

关于Java网络服务: User defined meta-data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22197593/

相关文章:

php - 我收到一个 fb_authToken 并想通过 fb_id 使用 PHP 验证它是否具有 session 和/或属于用户

eclipse - 你如何集成 gradle 和 jboss 6 来生成工作的 eclipse 项目

java - 配置更改无需重新部署

java - 使用 Spring Security BCryptPasswordEncoder 散列密码时凭据错误

java - 为什么我在 android 上使用 opencv 时会出现蓝色效果?

java - 多维数组中的列排序

java - webelement 列表中的一些 webelements 值变为空白 如何等待 webelement 的每个值出现在 selenium 的 webelements 中

java - CXF和spring如何相互支持

iphone - 带有 Web 服务的核心数据推荐模式?

java - 在 JBoss 配置中加密敏感信息