gpt4 book ai didi

web-services - 使用纯 JAX-WS 添加 SOAP header 对象

转载 作者:太空宇宙 更新时间:2023-11-03 15:38:48 27 4
gpt4 key购买 nike

我正在尝试使用 JAX WSPayPal Express Checkout API 实现简单的 Web 服务客户端。 PayPal Express Checkout API 提供了 WSDL 文件,我能够使用 CXF 的 wsdl2java 实用程序从中生成 Java 类。

出于身份验证的原因,它要求在每个请求中添加SOAP Header。这个 header 非常简单,应该如下所示: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECSOAPAPIBasics#id09C3I0CF0O6

WSDL 类生成,包括 ebay.apis.eblbasecomponents.CustomSecurityHeaderType 类,它表示我需要添加到每个请求的 header 。

所以问题是:考虑到以下条件,如何将手动创建的 CustomSecurityHeaderType 类实例添加到 SOAP 请求的 header 中:

  1. 我不太愿意使用 com.sun.* 包中的类,如此处的回答所述:JAX-WS - Adding SOAP Headers (主要是因为不同 JDK 之间可能存在的可移植性问题)
  2. 我不想将该对象手动编码到嵌套 javax.xml.soap.SOAPElement 实例中,如此处的回答中所述: How do I add a SOAP Header using Java JAX-WS

最佳答案

所以,看起来我在结合 JAX-WSJAXB 来自 SO 的相关答案时找到了可能的答案(我真的很想如果有这些技术经验的人可以检查以下内容是否正确,我将不胜感激):

对我来说显而易见的事情是添加 SOAP 消息处理程序并在其中更改 SOAPMessage 实例的 header :

import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.soap.SOAPHeader;
import ebay.api.paypalapi.ObjectFactory; // class generated by wsdl2java

// following class is generated by wsdl2java utility Service class
final PayPalAPIInterfaceService payPalService = new PayPalAPIInterfaceService();
final PayPalAPIAAInterface expressCheckoutPort = payPalService.getPayPalAPIAA();
final Binding binding = ((BindingProvider) expressCheckoutPort).getBinding();
List<Handler> handlersList = new ArrayList<Handler>();

// now, adding instance of Handler to handlersList which should do our job:
// creating header instance
final CustomSecurityHeaderType headerObj = new CustomSecurityHeaderType();
final UserIdPasswordType credentials = new UserIdPasswordType();
credentials.setUsername("username");
credentials.setPassword("password");
credentials.setSignature("signature");
headerObj.setCredentials(credentials);

// bookmark #1 - please read explanation after code
final ObjectFactory objectFactory = new ObjectFactory();
// creating JAXBElement from headerObj
final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);

handlersList.add(new SOAPHandler<SOAPMessageContext>() {
@Override
public boolean handleMessage(final SOAPMessageContext context) {
try {
// checking whether handled message is outbound one as per Martin Strauss answer
final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(requesterCredentials, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}

// ... default implementations of other methods go here

});

// as per Jean-Bernard Pellerin's comment setting handlerChain list here, after all handlers were added to list
binding.setHandlerChain(handlersList);

书签 #1 的解释:不应编码 header 对象本身,而应编码表示该对象的 JAXBElement,否则会出现异常。应该使用从 WSDL 生成的 ObjectFactory 类之一来从原始对象创建所需的 JAXBElement 实例。(感谢@skaffman 的回答:No @XmlRootElement generated by JAXB)

还应该引用扩展此问题的Martin Straus答案

关于web-services - 使用纯 JAX-WS 添加 SOAP header 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10654608/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com