我已经设法解决了这个问题,感谢@GPI提供的提示。我对Spring WS和javax.xml.whatever都比较新,所以无法确定这是正确或优雅的方式,但它确实做到了我想要的效果。
此代码基于通过JAXB从XSD模式生成的对象将自定义头元素添加到中。我不知道转换器如何知道我想把这些元素放在哪里,但它会将它们正确地放在头部节中。
public class HeaderComposingCallback implements WebServiceMessageCallback {
private final String action;
public HeaderComposingCallback( String action ) {
this.action = action;
}
@Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
SoapHeader soapHeader = ((SoapMessage)webServiceMessage).getSoapHeader();
try {
JAXBContext context = JAXBContext.newInstance( MessageHeader.class, Security.class );
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document securityDocument = builder.newDocument();
Document headerDocument = builder.newDocument();
Marshaller marshaller = context.createMarshaller();
marshaller.marshal( HeaderFactory.getHeader( action ), headerDocument );
marshaller.marshal( SecurityFactory.getSecurity(), securityDocument );
Transformer t = TransformerFactory.newInstance().newTransformer();
DOMSource headerSource = new DOMSource( headerDocument );
DOMSource securitySource = new DOMSource( securityDocument );
t.transform( headerSource, soapHeader.getResult() );
t.transform( securitySource, soapHeader.getResult() );
} catch (JAXBException | ParserConfigurationException e) {
e.printStackTrace();
}
}
}
然后,在服务调用期间,我只需要将HeaderComposingCallback
对象传递给marshalSendAndReceive()
方法即可。
编辑(根据Arjen的评论)
Arjen是正确的。我想要做的事情可以更简单地实现。现在我的doWithMessage
方法如下所示:
@Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
SoapHeader soapHeader = ((SoapMessage)webServiceMessage).getSoapHeader();
try {
JAXBContext context = JAXBContext.newInstance( MessageHeader.class, Security.class );
Marshaller marshaller = context.createMarshaller();
marshaller.marshal( header, soapHeader.getResult() );
marshaller.marshal( security, soapHeader.getResult() );
} catch (JAXBException e) {
e.printStackTrace();
}
}
Wss4jSecurityInterceptor
(它使用与 CXF、WSS4J 相同的 WS Security 库),配置正确的操作,然后它会为你完成工作... - GPIWss4jSecurityInterceptor
只是从头开始创建头的另一种方式,而我有完全组合的对象,我想将其插入头部。 - nachteil