I have a class generated with JAXB2 form a WSDL. The elements defined in the WSDL are NOT declared as XmlRootElement.
@Service
public class ProblemService extends WebServiceGatewaySupport {
public ProblemResponse addProblem(final Problem problem, final String aNumber) {
final String namespacePrefix = "soapenv";
final String action = "Problem";
final ObjectFactory factory = new ObjectFactory();
final JAXBElement<Problem> request = factory.createProblem(problem);
try {
StringResult result = new StringResult();
getMarshaller().marshal(request, result);
System.out.println(result.toString());
} catch (Exception e) {
e.printStackTrace(System.err);
}
final WebServiceTemplate wst = this.getWebServiceTemplate();
@SuppressWarnings("unchecked")
final JAXBElement<ProblemResponse> response = (JAXBElement<ProblemResponse>) wst
.marshalSendAndReceive(abcConfiguration.getEndpoint(), request, new WebServiceMessageCallback() {
@Override
public void doWithMessage(final WebServiceMessage message) {
try {
prepareSoapHeader(message, namespacePrefix, action);
final SaajSoapMessage ssMessage = (SaajSoapMessage) message;
final SOAPEnvelope envelope = ssMessage.getSaajMessage().getSOAPPart().getEnvelope();
envelope.getBody().setPrefix(namespacePrefix);
final NodeList nl = ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody().getChildNodes();
ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody().removeChild(nl.item(0));
final SOAPElement se = ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody()
.addBodyElement(new QName(action));
se.setPrefix(NAMESPACE_PREFIX_V2);
addUserAuthentification(se);
try {
StringResult result = new StringResult();
getAbcConfiguration().marshaller().marshal(request, result);
System.out.println(result.toString());
} catch (Exception e) {
e.printStackTrace(System.err);
}
System.out.println();
} catch (SoapFaultClientException e) {
logger.error("Error on client side during marshalling of the SOAP request for {}.", action, e);
} catch (SOAPException e) {
logger.error("Error during marshalling of the SOAP request for {}.", action, e);
}
}
});
return response.getValue();
}
}
The generated StringResult
looks quiet good but I need to replace some parts in the resulting XML (for instance the prefix) and I need to add some stuff into the SoapBody which are not part of the base class (Problem
) before sending the SOAP request to the remote service.
Furthermore I want to modify the header part of the envelope... How can I achieve this? My application is a SpringBoot application and in the configuration class being used in my service the un-/marshaller are defined this way:
@Bean
public Jaxb2Marshaller marshaller() {
final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
//setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setContextPath(contextPath);
//marshaller.afterPropertiesSet();
marshaller.setMarshallerProperties(new HashMap<String, Object>() {{
put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
}});
return marshaller;
}
@Bean
public ProblemService problemService(final Jaxb2Marshaller marshaller) throws Exception {
final ProblemService client = new ProblemService();
client.setDefaultUri(this.endpoint);
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
final HttpsUrlConnectionMessageSender msgSender = new HttpsUrlConnectionMessageSender();
client.setMessageSenders(new WebServiceMessageSender[] {msgSender, httpComponentsMessageSender()});
//client.setMessageSender(msgSender);
return client;
}
With this little piece of code I was able to add information to the SoapBody as demanded: