java web服务客户端,添加http头
在wsdl上使用wsimport创建了一个java Web服务客户端,我需要为http请求中嵌入的每个soap消息设置Authorization头。 生成了javax.xml.ws.Service的子类后,如何将http标头附加到每个传出请求?
您可以将带有自定义标头的地图传递给BindingProvider(我相信您可以设置MessageContext.HTTP_REQUEST_HEADERS属性)。 尝试创建Authorization标头并将其传入。
这是基于Femi答案的代码。
弄明白这可能有点棘手。 工作得很漂亮!
Service jaxwsService = Service.create(wsdlURL, serviceName); Dispatch disp = jaxwsService.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE); //Add HTTP request Headers Map> requestHeaders = new HashMap<>(); requestHeaders.put("Auth-User", Arrays.asList("BILL_GATES")); disp.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);
为了完整性和帮助处于类似情况的其他人,我想用JAX-WS-handler-chain来说明IMHO最干净的解决方案:
1)在不同(非生成)的包中对您的服务类(不是端口类)进行子类化。 因为服务类(及其整个包)可能是从WSDL生成的,所以当您在WSDL更改后更新服务类时,对子类的更改不会丢失。
2)像这样注释你的服务子类(import javax.jws.HandlerChain
):
@HandlerChain(file="HandlerChain.xml") public class MyService extends GeneratedService {
3)在与service-sub-class相同的包中创建一个名为HandlerChain.xml
的文件,即MyService
旁边的文件,其中包含以下内容:
co.codewizards.example.HttpHeaderExtensionSOAPHandler co.codewizards.example.HttpHeaderExtensionSOAPHandler
您可以添加多个
元素,顺便说一句。
并确保此文件真正在您的JAR中结束! 例如,在使用Maven时,您必须将它放在${project}/src/main/resources/
(而不是${project}/src/main/java/
)中,或者您必须将构建配置更改为包含来自java
夹的资源! 我推荐后者,因为在resources
-folder中有一个并行的包结构是很麻烦的,在重构期间经常会忘记它。
4)实现你的HttpHeaderExtensionSOAPHandler
– 类似于:
import static com.google.common.base.Preconditions.*; import java.util.*; import javax.xml.namespace.QName; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import co.codewizards.webservice.WebserviceContext; public class HttpHeaderExtensionSOAPHandler implements SOAPHandler { @Override public boolean handleMessage(SOAPMessageContext context) { checkNotNull(context, "context"); Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); checkNotNull(outboundProperty, "outboundProperty"); if (outboundProperty.booleanValue()) { WebserviceContext, ?> webserviceContext = WebserviceContext.getThreadWebserviceContextOrFail(); String something = (String) webserviceContext.___(); // my API method ;-) @SuppressWarnings("unchecked") Map> requestHeaders = (Map>) context.get(MessageContext.HTTP_REQUEST_HEADERS); if (requestHeaders == null) { requestHeaders = new HashMap>(); context.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders); } requestHeaders.put(MyService.MY_CONSTANT, Collections.singletonList(something)); } return true; } @Override public boolean handleFault(SOAPMessageContext context) { return true; } @Override public void close(MessageContext context) { } @Override public Set getHeaders() { return Collections.emptySet(); } }
在上面的例子中(以及我的高效代码中),我获取了要从ThreadLocale
传递到HTTP请求头的数据,即我当前线程的上下文。 由于此WebserviceContext
是我的自定义类,因此您需要实现自己的方式来访问数据。
当您在消息模式下发送时,您还可以在SOAP消息上传递MimeHeaders,最终将转换为http标头,即:
soapMessage.getMimeHeaders().addHeader("Authorization","Basic [md5]")