如何使用JAX-WS将SOAP头添加到SOAP请求?
我们需要使用其他团队开发的webservices。使用JAX-WS
生成Web服务。我们使用wsimport来生成客户端存根。如何使用JAX-WS将SOAP头添加到SOAP请求?
的问题是,我需要通过以下信息作为头与SOAP体沿:
<soapenv:Header>
<ns1:HeaderData xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:ns1="http://www.example.com/esb/data_type/HeaderData/v1">
<ChannelIdentifier>ABC</ChannelIdentifier>
</ns1:HeaderData>
</soapenv:Header>
我们使用:
BindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
serviceConfig.getServiceEndPoint()
);
设置终点。
任何人都可以建议如何传递标头与请求?
谢谢, VK
使用PARAM header = true
的@WebParam
注释
@WebMethod
@WebResult String method(
@WebParam String anotherParam
@WebParam(header = true, mode = Mode.OUT) Holder<String> headerParam)
header = true, mode = Mode.OUT
意味着PARAM headerParam
将仅在首部输出。
如果你想这个这个PARAM输入和输出,使Mode.INOUT
我不得不添加的用户凭据到页眉所以我做了这样的:
private void modifyRequest(String username, String password) {
UserCredentials authHeader = new UserCredentials();
authHeader.setUsername(username);
authHeader.setPassword(password);
ArrayList<Header> headers = new ArrayList<Header>(1);
try {
Header soapHeader = new Header(new QName(TQIntegrationV2.TQIntegrationV2Soap.getNamespaceURI(), "UserCredentials"), authHeader, new JAXBDataBinding(UserCredentials.class));
headers.add(soapHeader);
} catch (JAXBException ex) {
LOGGER.error("Exception trying to serialize header: {}", ex);
}
((BindingProvider) proxy).getRequestContext().put(Header.HEADER_LIST, headers);
}
,一切工作正常。每次对Web服务的调用都附带传递给此标头的用户名和密码。你可以很容易地改变这个在你的情况下工作。
EDIT
上面的代码使用CXF
API来修改标头。我也使用JAX-WS
来完成此操作。它几乎是相同的,修改标题添加的用户凭据:
public class MyHandler implements SOAPHandler<SOAPMessageContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class);
private String username;
private String password;
/**
* Handles SOAP message. If SOAP header does not already exist, then method will created new SOAP header. The
* username and password is added to the header as the credentials to authenticate user. If no user credentials is
* specified every call to web service will fail.
*
* @param context SOAP message context to get SOAP message from
* @return true
*/
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
SOAPMessage message = context.getMessage();
SOAPHeader header = message.getSOAPHeader();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
if (header == null) {
header = envelope.addHeader();
}
QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials");
SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials);
QName qNameUsername = new QName("https://your.target.namespace/", "Username");
SOAPHeaderElement username = header.addHeaderElement(qNameUsername);
username.addTextNode(this.username);
QName qNamePassword = new QName("https://your.target.namespace/", "Password");
SOAPHeaderElement password = header.addHeaderElement(qNamePassword);
password.addTextNode(this.password);
userCredentials.addChildElement(username);
userCredentials.addChildElement(password);
message.saveChanges();
//TODO: remove this writer when the testing is finished
StringWriter writer = new StringWriter();
message.writeTo(new StringOutputStream(writer));
LOGGER.debug("SOAP message: \n" + writer.toString());
} catch (SOAPException e) {
LOGGER.error("Error occurred while adding credentials to SOAP header.", e);
} catch (IOException e) {
LOGGER.error("Error occurred while writing message to output stream.", e);
}
return true;
}
//TODO: remove this class after testing is finished
private static class StringOutputStream extends OutputStream {
private StringWriter writer;
public StringOutputStream(StringWriter writer) {
this.writer = writer;
}
@Override
public void write(int b) throws IOException {
writer.write(b);
}
}
@Override
public boolean handleFault(SOAPMessageContext context) {
LOGGER.debug("handleFault has been invoked.");
return true;
}
@Override
public void close(MessageContext context) {
LOGGER.debug("close has been invoked.");
}
@Override
public Set<QName> getHeaders() {
LOGGER.debug("getHeaders has been invoked.");
return null;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
我在Spring
配置定义该处理程序是这样的:
<bean id="soapHandler" class="your.package.MyHandler">
<property name="username" value="testUser"/>
<property name="password" value="testPassword"/>
</bean>
<jaxws:client "...">
<jaxws:handlers>
<ref bean="soapHandler"/>
</jaxws:handlers>
</jaxws:client>
所有你需要做的是落实SOAPHandler<SOAPMessageContext>
接口,重写它的方法,然后你可以用SOAP
消息做你想做的事。
感谢您的回复。你能发布Header类的完全限定名吗?只是想找出它是否来自jaxws api。 – ikvenu2000
头文件不是来自CXF的JAX-WS,而是编辑了如何修改JAX-WS头文件的答案。 –
JAX-WS代码完美工作,谢谢! – kai
这个答案应该被接受。简洁而准确。 –