from - Obtención de XML sin procesar desde SOAPMessage en Java
jax-ws java 8 (8)
Podrías probar de esta manera.
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
Configuré SOAP WebServiceProvider en JAX-WS, pero tengo problemas para averiguar cómo obtener el XML sin formato desde un objeto SOAPMessage (o cualquier nodo). Aquí hay una muestra del código que tengo ahora, y donde estoy tratando de tomar el 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?
}
}
¿Hay una manera simple de obtener el XML de la solicitud original? Si hay una forma de obtener el XML sin procesar configurando un tipo diferente de Proveedor (como Fuente), estaría dispuesto a hacerlo también.
Resulta que uno puede obtener el XML sin procesar usando Provider <Source>, de esta manera:
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;
}
}
Terminé sin necesitar esta solución, por lo que en realidad no he probado este código por mí mismo, podría necesitar algunos ajustes para hacerlo bien. Pero sé que este es el camino correcto para bajar para obtener el XML sin formato de un servicio web.
(No estoy seguro de cómo hacer que esto funcione si es absolutamente necesario tener un objeto SOAPMessage, pero de nuevo, si va a manejar el XML sin procesar de todos modos, ¿por qué usaría un objeto de nivel superior?)
Si necesita formatear la cadena xml a xml, intente esto:
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")));
Si tiene un SOAPMessage
o SOAPMessageContext
, puede usar un Transformer
, convirtiéndolo a un Source
través de 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());
Esto tendrá en cuenta la codificación, por lo que tus "caracteres especiales" no se destrozarán.
Usando la fábrica de transformadores: -
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();
}
esto funciona
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();
para solo propósito de depuración, use un código de línea -
msg.writeTo(System.out);
si tiene el código de cliente, entonces solo necesita agregar las siguientes dos líneas para obtener la solicitud / respuesta XML. Aquí _call
es org.apache.axis.client.Call
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();