JAX-WS - 添加SOAP标头

问题描述:

我正在尝试创建一个独立的客户端来使用一些Web服务。我必须将我的用户名和密码添加到SOAP Header中。我尝试添加凭据,如下所示:

I am trying to create a standalone client to consume some web services. I must add my username and password to the SOAP Header. I tried adding the credentials as follows:

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");

...

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

When I call a method on the service I get the following exception:

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

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

What am I doing wrong? How would I add these properties to the SOAP Header?

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

Edited: I was using JAX-WS 2.1 included in JDK6. I am now using JAX-WS 2.2. I now get the following exception:

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.

如何创建此令牌?

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

Not 100% sure as the question is missing some details but if you are using JAX-WS RI, then have a look at Adding SOAP headers when sending requests:


执行此操作的可移植方式是
您创建 SOAPHandler 并且与SAAJ一起使用
,但是RI提供了一个
更好的方法。

The portable way of doing this is that you create a SOAPHandler and mess with SAAJ, but the RI provides a better way of doing this.

当你创建代理或派遣
对象时,他们实现
BindingProvider 界面。当
使用JAX-WS RI时,你可以向下转换为
WSBindingProvider ,它定义了
更多的方法,仅由$提供b $ b JAX-WS RI。

When you create a proxy or dispatch object, they implement BindingProvider interface. When you use the JAX-WS RI, you can downcast to WSBindingProvider which defines a few more methods provided only by the JAX-WS RI.

此接口允许您设置
任意数量的Header对象,每个
表示一个SOAP标头。你
可以自己实现它,如果你想要
,但很可能你使用
中的一个
标题中定义的工厂方法创建一个类。

This interface lets you set an arbitrary number of Header object, each representing a SOAP header. You can implement it on your own if you want, but most likely you'd use one of the factory methods defined on Headers class to create one.

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,请更新您的问题并提供更多背景信息。

Update your code accordingly and try again. And if you're not using JAX-WS RI, please update your question and provide more context information.

更新它似乎是要使用WS-Security / UsernameTokens保护要调用的Web服务。这与您最初的问题略有不同。无论如何,要配置你的客户端发送用户名和密码,我建议检查一下这篇文章为基于Metro的Web服务实现WS-Security UsernameToken配置文件(跳转到第4步)。在此步骤中使用NetBeans可能会减轻很多事情。

Update: It appears that the web service you want to call is secured with WS-Security/UsernameTokens. This is a bit different from your initial question. Anyway, to configure your client to send usernames and passwords, I suggest to check the great post Implementing the WS-Security UsernameToken Profile for Metro-based web services (jump to step 4). Using NetBeans for this step might ease things a lot.