Domanda

Ho creato un WebServiceProvider SOAP in JAX-WS, ma sto avendo problemi a capire come ottenere il codice XML grezzo da un SOAPMessage (o qualsiasi nodo) oggetto. Ecco un esempio del codice che ho in questo momento, e dove sto cercando di afferrare l'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?
    }
}

C'è un modo semplice per ottenere il codice XML della richiesta originale? Se c'è un modo per ottenere il codice XML grezzo attraverso la creazione di un diverso tipo di provider (come ad esempio Source), sarei disposto a farlo, anche.

È stato utile?

Soluzione 3

Si scopre che si può ottenere l'XML grezzo utilizzando Provider , in questo modo:

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;
    }
}

Non ho finito per non necessitano di questa soluzione, così non ho effettivamente provato questo codice stesso - potrebbe avere bisogno di qualche ritocco per ottenere destra. Ma so che questa è la strada giusta per andare giù per ottenere il codice XML grezzo da un servizio Web.

(io non sono sicuro di come fare questo lavoro se si deve assolutamente avere un oggetto SOAPMessage, ma poi di nuovo, se si sta andando ad essere la gestione del XML grezzo in ogni modo, il motivo per cui si usa un oggetto di livello superiore? )

Altri suggerimenti

Si potrebbe provare in questo modo.

SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());

Se si dispone di un SOAPMessage o SOAPMessageContext, è possibile utilizzare un Transformer, convertendolo in un 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());

Questo richiederà la codifica in considerazione, in modo che le "caratteri speciali" non sarà possibile ottenere straziati.

solo per il debug di scopo, utilizzare il codice di una riga -

msg.writeTo(System.out);

Se avete bisogno di formattare la stringa XML a XML, provare questo:

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")));

Uso del trasformatore di fabbrica: -

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();
    }

questo funziona

 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();

se hai il codice del client, allora non vi resta che aggiungere le seguenti due righe per ottenere la richiesta XML / risposta. Qui _call è org.apache.axis.client.Call

String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();

E 'piuttosto vecchio thread, ma di recente ho avuto un problema simile. Ho chiamato un servizio di sapone a valle, da un servizio di riposo, e avevo bisogno di restituire la risposta XML proveniente dal server a valle come è.

Così, ho finito per l'aggiunta di un gestore SoapMessageContext per ottenere la risposta XML. Poi i iniettato il XML risposta in contesto servlet come attributo.

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;
            }
        }

Poi ho recuperato la stringa di risposta XML nel livello di servizio.

ServletContext servletContext =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();

        String msg = (String) servletContext.getAttribute("responseXml");

Non abbiamo avuto la possibilità di provare ancora, ma questo approccio deve essere thread-safe, poiché utilizza il contesto servlet.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top