J'ai configuré un SOAP WebServiceProvider dans JAX-WS, mais je ne parviens pas à comprendre comment obtenir le XML brut à partir d'un objet SOAPMessage (ou de n'importe quel nœud). Voici un exemple du code que j'ai en ce moment, et où j'essaie de récupérer le XML:
@WebServiceProvider(wsdlLocation="SoapService.wsdl")
@ServiceMode(value=Service.Mode.MESSAGE)
public class SoapProvider implements Provider<SOAPMessage>
{
public SOAPMessage invoke(SOAPMessage msg)
{
// How do I get the raw XML here?
}
}
Existe-t-il un moyen simple d’obtenir le code XML de la demande initiale? S'il existe un moyen d'obtenir le code XML brut en configurant un type de fournisseur différent (tel que Source), je serais prêt à le faire également.
Il s'avère que l'on peut obtenir le XML brut en utilisant Fournisseur <Source>, de la manière suivante:
import Java.io.ByteArrayOutputStream;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
@ServiceMode(value=Service.Mode.PAYLOAD)
@WebServiceProvider()
public class SoapProvider implements Provider<Source>
{
public Source invoke(Source msg)
{
StreamResult sr = new StreamResult();
ByteArrayOutputStream out = new ByteArrayOutputStream();
sr.setOutputStream(out);
try {
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(msg, sr);
// Use out to your heart's desire.
}
catch (TransformerException e) {
e.printStackTrace();
}
return msg;
}
}
En fin de compte, je n'ai plus besoin de cette solution. Je n'ai donc pas essayé ce code moi-même. Il faudra peut-être un peu de peaufinage pour réussir. Mais je sais que c’est le bon chemin à suivre pour obtenir le code XML brut d’un service Web.
(Je ne sais pas comment faire pour que cela fonctionne si vous devez absolument disposer d'un objet SOAPMessage, mais encore une fois, si vous allez gérer le XML brut de toute façon, pourquoi utiliseriez-vous un objet de niveau supérieur?)
Vous pouvez essayer de cette façon.
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
Si vous avez SOAPMessage
ou SOAPMessageContext
, vous pouvez utiliser un Transformer
en le convertissant en Source
via DOMSource
:
final SOAPMessage message = messageContext.getMessage();
final StringWriter sw = new StringWriter();
try {
TransformerFactory.newInstance().newTransformer().transform(
new DOMSource(message.getSOAPPart()),
new StreamResult(sw));
} catch (TransformerException e) {
throw new RuntimeException(e);
}
// Now you have the XML as a String:
System.out.println(sw.toString());
Cela tiendra compte de l’encodage afin que vos "caractères spéciaux" ne soient pas mutilés.
Si vous avez besoin de formater la chaîne XML en XML, essayez ceci:
String xmlStr = "your-xml-string";
Source xmlInput = new StreamSource(new StringReader(xmlStr));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.Apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput,
new StreamResult(new FileOutputStream("response.xml")));
Utilisation de Transformer Factory: -
public static String printSoapMessage(final SOAPMessage soapMessage) throws TransformerFactoryConfigurationError,
TransformerConfigurationException, SOAPException, TransformerException
{
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
final Transformer transformer = transformerFactory.newTransformer();
// Format it
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.Apache.org/xslt}indent-amount", "2");
final Source soapContent = soapMessage.getSOAPPart().getContent();
final ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
final StreamResult result = new StreamResult(streamOut);
transformer.transform(soapContent, result);
return streamOut.toString();
}
cela marche
final StringWriter sw = new StringWriter();
try {
TransformerFactory.newInstance().newTransformer().transform(
new DOMSource(soapResponse.getSOAPPart()),
new StreamResult(sw));
} catch (TransformerException e) {
throw new RuntimeException(e);
}
System.out.println(sw.toString());
return sw.toString();
C'est assez vieux fil mais récemment j'ai eu un problème similaire. J'appelais un service soap en aval, à partir d'un service de repos, et je devais renvoyer la réponse XML provenant du serveur en aval telle quelle.
Donc, j'ai fini par ajouter un gestionnaire SoapMessageContext pour obtenir la réponse XML. Ensuite, j’ai injecté la réponse XML dans un contexte de servlet en tant qu’attribut.
public boolean handleMessage(SOAPMessageContext context) {
// Get xml response
try {
ServletContext servletContext =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();
SOAPMessage msg = context.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
servletContext.setAttribute("responseXml", strMsg);
return true;
} catch (Exception e) {
return false;
}
}
Ensuite, j'ai récupéré la chaîne de réponse XML dans la couche de service.
ServletContext servletContext =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();
String msg = (String) servletContext.getAttribute("responseXml");
Nous n'avons pas encore eu l'occasion de le tester, mais cette approche doit être thread-safe car elle utilise le contexte de servlet.
si vous avez le code client, il vous suffit d'ajouter les deux lignes suivantes pour obtenir la requête/réponse XML. Ici _call
est org.Apache.axis.client.Call
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();