Как добавить заголовки SOAP в Spring Jax-WS Client?
Как добавить заголовки SOAP в Spring Jax-WS Client?
В частности, у меня есть объект Jaxb, который я хотел бы добавить в заголовок, но xml-примеры будут оценены.
Я использую Spring JaxWsPortProxyFactoryBean, описанный здесь здесь. Кроме того, я создаю свой клиент, как описано здесь, который работает меньше заголовков, которые мне нужно добавить.
Спасибо.
Ответы
Ответ 1
Немного более изящный (требуется классный класс):
public void doWithMessage(WebServiceMessage message) {
try {
SOAPMessage soapMessage = ((SaajSoapMessage)message).getSaajMessage();
SOAPHeader header = soapMessage.getSOAPHeader();
SOAPHeaderElement security = header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2003/06/secext", "Security", "wsse"));
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
username.setTextContent(someUsername);
password.setTextContent(somePassword);
} catch (Exception e) {
//... handle appropriately
}
}
Примечание. В этом примере были тестеры с Spring WS 2.1.4.
Ответ 2
Я все еще пытаюсь найти элегантный способ добавления заголовков, но то, что я делаю по предложению других, это использовать Transformer в WebServiceMessageCallBack(). Вот пример кода:
JAXBElement<GetDeletedResponse> result = (JAXBElement<GetDeletedResponse>) webServiceTemplate.marshalSendAndReceive(request, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage webServiceMessage) {
try {
SoapMessage soapMessage = (SoapMessage) webServiceMessage;
soapMessage.setSoapAction("getDeleted");
SoapHeader header = soapMessage.getSoapHeader();
StringSource headerSource = new StringSource("<account>\n" +
"<username>"+"johnsmith"+"</username>\n" +
"<password>"+"1234"+"</password>\n" +
"</account>");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, header.getResult());
} catch (Exception e) {
new RuntimeException(e);
}
}
...
Это не очень элегантно, учитывая, что это Spring WS. Это не интуитивно.
Ответ 3
После того, как некоторые выкалывают, если нашли немного другое решение. Я использую JAXB для сортировки моей полезной нагрузки, а также возможные классы заголовков также были созданы с помощью JAXB из WSDL.
В моем случае я обращаюсь к службам Microsoft Reporting Services и передаю ExecutionID как заголовок SOAP.
public class ReportExecution2005Client extends WebServiceGatewaySupport {
private static final String SET_EXECUTION_PARAMETERS_ACTION = "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/SetExecutionParameters";
private final class SoapActionExecutionIdCallback implements WebServiceMessageCallback {
private final String soapAction;
private final String executionId;
public SoapActionExecutionIdCallback(String soapAction, String executionId) {
super();
this.soapAction = soapAction;
this.executionId = executionId;
}
@Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
SoapMessage soapMessage = (SoapMessage) message;
soapMessage.setSoapAction(soapAction);
ExecutionHeader executionHeader = new ExecutionHeader();
executionHeader.setExecutionID(executionId);
getMarshaller().marshal(executionHeader, soapMessage.getSoapHeader().getResult());
}
}
public void setExecutionParameters(String executionId){
SetExecutionParameters request = new SetExecutionParameters();
request.setParameters(new ArrayOfParameterValue());
SetExecutionParametersResponse response = (SetExecutionParametersResponse) getWebServiceTemplate().marshalSendAndReceive(request,
new SoapActionExecutionIdCallback(
SET_EXECUTION_PARAMETERS_ACTION,
executionId));
}
}
В основном WebServiceGatewaySupport уже знает маршаллера для преобразования JAXB Pojos. Я использую эту, чтобы присоединить свои собственные классы заголовков к SoapHeader с помощью этой строки:
getMarshaller().marshal(executionHeader, soapMessage.getSoapHeader().getResult());
в моем вложенном WebServiceMessageCallback.