Web服务 – 使用纯JAX-WS添加SOAP头对象

前端之家收集整理的这篇文章主要介绍了Web服务 – 使用纯JAX-WS添加SOAP头对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图使用JAX WS实现PayPal Express Checkout API的简单Web服务客户端。 PayPal Express Checkout API提供WSDL文件,我可以使用CXF的wsdl2java实用程序生成Java类。

从认证的原因,它要求为每个请求添加SOAP头。这个标题很简单,应该看起来像这样:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECSOAPAPIBasics#id09C3I0CF0O6

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

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

>我不是非常渴望使用com.sun。*包中的类,如答案所述:JAX-WS – Adding SOAP Headers(主要是因为不同JDK之间可能的可移植性问题)
>我不想手动将该对象编组到嵌套的javax.xml.soap.SOAPElement实例中,如下所述:
How do I add a SOAP Header using Java JAX-WS

解决方法

所以,看起来我已经找到可能的答案,而JAX-WS&来自SO的JAXB相关答案(如果有人在这些技术中有经验可以检查以下是否正确,我真的很感激):

对我来说显而易见的是在其中添加SOAP消息处理程序和SOAPMessage实例的alter头:

  1. import javax.xml.ws.Binding;
  2. import javax.xml.ws.BindingProvider;
  3. import javax.xml.ws.handler.Handler;
  4. import javax.xml.bind.JAXBContext;
  5. import javax.xml.bind.JAXBElement;
  6. import javax.xml.bind.Marshaller;
  7. import javax.xml.soap.SOAPHeader;
  8. import ebay.api.paypalapi.ObjectFactory; // class generated by wsdl2java
  9.  
  10. // following class is generated by wsdl2java utility Service class
  11. final PayPalAPIInterfaceService payPalService = new PayPalAPIInterfaceService();
  12. final PayPalAPIAAInterface expressCheckoutPort = payPalService.getPayPalAPIAA();
  13. final Binding binding = ((BindingProvider) expressCheckoutPort).getBinding();
  14. List<Handler> handlersList = new ArrayList<Handler>();
  15.  
  16. // now,adding instance of Handler to handlersList which should do our job:
  17. // creating header instance
  18. final CustomSecurityHeaderType headerObj = new CustomSecurityHeaderType();
  19. final UserIdPasswordType credentials = new UserIdPasswordType();
  20. credentials.setUsername("username");
  21. credentials.setPassword("password");
  22. credentials.setSignature("signature");
  23. headerObj.setCredentials(credentials);
  24.  
  25. // bookmark #1 - please read explanation after code
  26. final ObjectFactory objectFactory = new ObjectFactory();
  27. // creating JAXBElement from headerObj
  28. final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);
  29.  
  30. handlersList.add(new SOAPHandler<SOAPMessageContext>() {
  31. @Override
  32. public boolean handleMessage(final SOAPMessageContext context) {
  33. try {
  34. // checking whether handled message is outbound one as per Martin Strauss answer
  35. final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
  36. if (outbound != null && outbound) {
  37. // obtaining marshaller which should marshal instance to xml
  38. final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
  39. // adding header because otherwise it's null
  40. final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
  41. // marshalling instance (appending) to SOAP header's xml node
  42. marshaller.marshal(requesterCredentials,soapHeader);
  43. }
  44. } catch (final Exception e) {
  45. throw new RuntimeException(e);
  46. }
  47. return true;
  48. }
  49.  
  50. // ... default implementations of other methods go here
  51.  
  52. });
  53.  
  54. // as per Jean-Bernard Pellerin's comment setting handlerChain list here,after all handlers were added to list
  55. binding.setHandlerChain(handlersList);

书签#1的说明:
应该不是头文件本身,而是代表该对象的JAXBElement,否则会得到异常。应该使用从WSDL生成的一个ObjectFactory类,以从原始对象创建所需的JAXBElement实例。
(感谢@skaffman的答案:No @XmlRootElement generated by JAXB)

还应该参考马丁·斯特劳斯(Martin Straus)的答案,这个答案扩展了这一点

猜你在找的HTML相关文章