Erste Raw XML Von Soapmessage in Java
Frage
Ich habe eine SOAP WebServiceProvider in JAX-WS einrichten, aber ich habe Probleme, herauszufinden, wie die XML-Rohdaten von einem Soapmessage zu bekommen (oder einem Node) Objekt. Hier ist ein Beispiel des Code, den ich jetzt habe, und wo ich versuche, die XML zu greifen:
@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?
}
}
Gibt es eine einfache Möglichkeit, die XML der ursprünglichen Anforderung zu bekommen? Wenn es ein Weg, um den XML-Rohdaten zu erhalten, indem eine andere Art von Provider (wie Quelle) einrichten, wäre ich bereit, das zu tun, auch.
Lösung 3
Es stellt sich heraus, dass man die rohen XML mithilfe von Provider bekommen
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;
}
}
Ich habe diese Lösung nicht benötigt beendet, so dass ich nicht wirklich diesen Code selbst ausprobiert - es könnte einige Optimierungen müssen richtig machen. Aber ich weiß, dass dies der richtige Weg ist, um die XML-Rohdaten von einem Webdienst zu gehen zu erhalten.
(Ich bin nicht sicher, wie diese Arbeit zu machen, wenn Sie unbedingt ein Soapmessage-Objekt haben muss, aber dann wieder, wenn Sie vorhaben, die XML-Rohdaten werden Handhabung sowieso, warum würden Sie verwenden, um ein übergeordnetes Objekt? )
Andere Tipps
Sie können auf diese Weise versuchen.
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
Wenn Sie ein SOAPMessage
oder SOAPMessageContext
haben, können Sie eine Transformer
verwenden, indem sie einen Source
über DOMSource
Umwandlung:
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());
Dies wird die Codierung berücksichtigt werden, so dass Ihre „Sonderzeichen“ nicht verstümmelt erhalten.
für nur Zweck debuggen, eine Zeile Code verwenden -
msg.writeTo(System.out);
Wenn Sie die XML-Zeichenfolge zu XML-Formatierung benötigen, versuchen Sie dies:
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")));
Mit Transformator 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();
}
Das funktioniert
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();
, wenn Sie den Client-Code haben, dann müssen Sie nur die folgenden zwei Zeilen hinzufügen, um die XML-Request / Response zu erhalten. Hier _call
ist org.apache.axis.client.Call
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
Es ist ziemlich alter Thread aber vor kurzem habe ich ein ähnliches Problem. Ich war ein nachgeschaltetes Seife Service, von einem Rest-Service anrufen, und ich brauchte die XML-Antwort von dem Downstream-Server kommt zurück, wie ist.
So endete ich einen SoapMessageContext Handler hinzugefügt, um die XML-Antwort zu erhalten. Dann injizierte ich die Antwort xml in Servlet-Kontext als ein 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;
}
}
Dann habe ich die XML-Antwortzeichenfolge in der Dienstschicht abgerufen werden.
ServletContext servletContext =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();
String msg = (String) servletContext.getAttribute("responseXml");
Sie haben nicht zufällig haben sie noch zu testen, aber dieser Ansatz muss sicher sein Thread, da es den Servlet-Kontext verwendet wird.