Java SpringSOAP拦截器如何修改消息的内容?
我正在尝试为web服务编写一个拦截器,该拦截器将在Soap消息发送到端点之前修改Soap消息的内容。如果客户端发送的消息中某个元素的值为1,我希望能够将该元素更改为2,这样,当消息到达端点时,客户端似乎提交了2而不是1。我不确定这是一项艰难的任务,还是一项简单的任务,让我变得比需要的更困难 我已经通过了一些Spring拦截器;但是验证和日志拦截器并不是每次都改变传输中的消息。Wss4jSecurityInterceptor确实向MessageContext添加了一些属性;但我无法利用它正在做的任何事情。我有一个拦截器的外壳;但没有什么是做任何有价值的事情Java SpringSOAP拦截器如何修改消息的内容?,java,web-services,soap,spring-ws,Java,Web Services,Soap,Spring Ws,我正在尝试为web服务编写一个拦截器,该拦截器将在Soap消息发送到端点之前修改Soap消息的内容。如果客户端发送的消息中某个元素的值为1,我希望能够将该元素更改为2,这样,当消息到达端点时,客户端似乎提交了2而不是1。我不确定这是一项艰难的任务,还是一项简单的任务,让我变得比需要的更困难 我已经通过了一些Spring拦截器;但是验证和日志拦截器并不是每次都改变传输中的消息。Wss4jSecurityInterceptor确实向MessageContext添加了一些属性;但我无法利用它正在做的任
public boolean handleRequest(MessageContext messageContext, Object endpoint)
throws Exception {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) messageContext
.getRequest();
SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
SOAPBody soapBody = soapMessage.getSOAPBody();
return true;
}
我希望soembody else有可能已经解决了这个特殊的问题。如有任何见解,将不胜感激。谢谢。修改有效负载有点棘手。我发现的唯一可行的方法是使用
SoapBody
上的getPayloadSource()
和getPayloadResult()
方法,它们公开了javax.xml.transform
友好的对象来操作数据
它的重量令人恼火,但你可以这样做:
Transformer identityTransform = TransformerFactory.newInstance().newTransformer();
DOMResult domResult = new DOMResult();
identityTransform.transform(soapBody.getPayloadSource(), domResult);
Node bodyContent = domResult.getNode(); // modify this
identityTransform.transform(new DOMSource(bodyContent), soapBody.getPayloadResult());
我很想看到一种更好的方法。我意识到以后修改请求更容易。我不需要修改原始SOAP消息,只要我能够在数据到达端点之前修改数据 我正在使用的端点都是extend AbstractDom4jPayloadEndpoint——因此我将这些端点包装在一个代理中,该代理允许我在继续使用端点之前修改请求元素。i、 e:
public class MyProxyEndpoint extends AbstractDom4jPayloadEndpoint
@Override
protected Element invokeInternal(
Element requestElement,
Document responseDocument ) throws Exception
{
if( requestElement != null )
{
// alter request element
}
return ( Element ) this.invokeMethod.invoke(
this.target,
requestElement,
responseDocument );
}
我修改了这个答案中的代码,将
元素插入到所有SOAP正文请求中:
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
logger.trace("Enter handleMessage");
try {
SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
addAuthn(request);
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
return true;
}
protected void addAuthn(SaajSoapMessage request) throws TransformerException {
Transformer identityTransform = TransformerFactory.newInstance().newTransformer();
DOMResult domResult = new DOMResult();
identityTransform.transform(request.getPayloadSource(), domResult);
Node bodyContent = domResult.getNode();
Document doc = (Document) bodyContent;
doc.getFirstChild().appendChild(authNode(doc));
identityTransform.transform(new DOMSource(bodyContent), request.getPayloadResult());
}
protected Node authNode(Document doc) {
Element authentication = doc.createElementNS(ns, "authentication");
Element username = doc.createElementNS(ns, "username");
username.setTextContent(authn.getUsername());
Element password = doc.createElementNS(ns, "password");
password.setTextContent(authn.getPassword());
authentication.appendChild(username);
authentication.appendChild(password);
return authentication;
}
之所以使用此解决方案,是因为WebServiceMessageCallback需要我更改文档,并且在配置的Jaxb2Marshaller插入soap正文之前,SaajSoapMessageFactory已被激活。谢谢。你说得对——这并不像人们希望的那样直截了当。我实际上用另一种方式解决了我的问题。虽然它没有直接解决我最初的问题,但它解决了我目前的问题。