Web服务 – 使用纯JAX-WS添加SOAP头对象
我试图使用JAX WS实现PayPal Express Checkout API的简单Web服务客户端。 PayPal Express Checkout API提供WSDL文件,我可以使用CXF的wsdl2java实用程序生成Java类。
从认证的原因,它要求为每个请求添加SOAP头。这个标题很简单,应该看起来像这样: 从WSDL类生成的包括ebay.apis.eblbasecomponents.CustomSecurityHeaderType类,它代表我需要添加到每个请求中的头。 所以问题是:如何将手动创建的CustomSecurityHeaderType类的实例添加到SOAP请求的头部,并考虑以下条件: >我不是非常渴望使用com.sun。*包中的类,如答案所述:JAX-WS – Adding SOAP Headers(主要是因为不同JDK之间可能的可移植性问题) 解决方法
所以,看起来我已经找到可能的答案,而JAX-WS&来自SO的JAXB相关答案(如果有人在这些技术中有经验可以检查以下是否正确,我真的很感激):
对我来说显而易见的是在其中添加SOAP消息处理程序和SOAPMessage实例的alter头: 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的说明: 还应该参考马丁·斯特劳斯(Martin Straus)的答案,这个答案扩展了这一点 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |