JAX-WS - 添加 SOAP 头文件

2022-09-01 05:35:37

我正在尝试创建一个独立的客户端来使用一些Web服务。我必须将我的用户名和密码添加到 SOAP 标头。我尝试按如下方式添加凭据:

OTSWebSvcsService service = new OTSWebSvcsService();
OTSWebSvcs port = service.getOTSWebSvcs();

BindingProvider prov = (BindingProvider)port;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");

...

当我在服务上调用方法时,我得到以下异常:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5048E: One of "SOAP Header" elements required.

我做错了什么?如何将这些属性添加到 SOAP 标头?

编辑:我使用的是JDK6中包含的JAX-WS 2.1。我现在正在使用 JAX-WS 2.2。我现在得到以下异常:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5509E: A security token whose type is [http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken] is required.

如何创建此令牌?


答案 1

数据可以通过使用@WebParam(header = true)在SOAP标头(JaxWS)中传输:

@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/")
@Oneway
public void sendRequest(
    @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message")
    Data message,
    @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader")
    Header serviceHeader);

如果要使用 SOAP 标头生成客户端,则需要使用 -XadditionalHeaders:

wsimport -keep -Xnocompile -XadditionalHeaders -Xdebug http://12.34.56.78:8080/TestHeaders/somewsdl?wsdl -d /home/evgeny/DEVELOPMENT/JAVA/gen

如果不需要@Oneway Web 服务,可以使用 Holder:

@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/")
public void sendRequest(
    @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message")
    Data message,
    @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader")
    Holder<Header> serviceHeader);

答案 2

不是100%确定,因为问题缺少一些细节,但如果您使用的是JAX-WS RI,那么请查看在发送请求时添加SOAP标头

执行此操作的便携式方法是创建一个并弄乱SAAJ,但RI提供了一种更好的方法来执行此操作。SOAPHandler

创建代理或调度对象时,它们实现接口。使用 JAX-WS RI 时,可以向下转换到它来定义仅由 JAX-WS RI 提供的更多方法。BindingProviderWSBindingProvider

此接口允许您设置任意数量的 Header 对象,每个对象表示一个 SOAP 标头。如果需要,您可以自己实现它,但最有可能的是,您可以使用在类上定义的工厂方法之一来创建一个。Headers

import com.sun.xml.ws.developer.WSBindingProvider;

HelloPort port = helloService.getHelloPort();  // or something like that...
WSBindingProvider bp = (WSBindingProvider)port;

bp.setOutboundHeader(
  // simple string value as a header, like <simpleHeader>stringValue</simpleHeader>
  Headers.create(new QName("simpleHeader"),"stringValue"),
  // create a header from JAXB object
  Headers.create(jaxbContext,myJaxbObject)
);

请相应地更新代码,然后重试。如果您没有使用 JAX-WS RI,请更新您的问题并提供更多上下文信息。

更新:看起来您要调用的 Web 服务已使用 WS-Security/UsernameTokens 进行保护。这与你最初的问题有点不同。无论如何,要将客户端配置为发送用户名和密码,我建议查看为基于Metro的Web服务实现WS-Security UsernameToken配置文件的精彩文章(跳到步骤4)。在此步骤中使用 NetBeans 可能会大大简化操作。


推荐