我试图拦截传出的SOAP消息并修改(即覆盖)SOAP标头。
为此,我制作了以下代码。虽然代码确实拦截了消息,但它将 new (即修改过的)SOAP标头作为原始SOAP标头的第二个子标记附加,而不是替换原始的SOAP标头。
我的印象是行:transformer.transform(new DOMSource(document), soapHeader.getResult());
将使用修改后的/新SOAP标头覆盖/替换原始SOAP标头。
有谁知道如何让新的SOAP标头取代原来的?
@Component
public class CustomClientInterceptor implements ClientInterceptor {
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
SoapMessage soapMessage = (SoapMessage) messageContext.getRequest();
SoapHeader soapHeader = soapMessage.getSoapHeader();
Source soapHeaderSource = soapHeader.getSource();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamResult soapHeaderResult = new StreamResult(outputStream);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringElementContentWhitespace(true);
documentBuilderFactory.setIgnoringComments(true);
Transformer transformer;
DocumentBuilder documentBuilder;
Document document;
StringWriter writer = new StringWriter();
try {
transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(soapHeaderSource, soapHeaderResult);
documentBuilder = documentBuilderFactory.newDocumentBuilder();
document = documentBuilder.parse(new ByteArrayInputStream(outputStream.toByteArray()));
NodeList signedInfoNodes = document.getElementsByTagName("ds:SignedInfo");
NodeList signatureValueNodes = document.getElementsByTagName("ds:SignatureValue");
Node signedInfoNode;
Node signatureValueNode;
String signedInfo;
String signedValue;
String canonicalSignedInfo;
if (signedInfoNodes.getLength() == 1 && signatureValueNodes.getLength() == 1) {
signedInfoNode = signedInfoNodes.item(0);
transformer.transform(new DOMSource(signedInfoNode), new StreamResult(writer));
signedInfo = writer.toString();
canonicalSignedInfo = canonicalize(signedInfo);
signedValue = computeSignature(SignatureAlgorithm.SHA1withRSA, canonicalSignedInfo);
signatureValueNode = signatureValueNodes.item(0);
signatureValueNode.setTextContent(signedValue);
transformer.transform(new DOMSource(document), soapHeader.getResult());
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return true;
}
...
}