Question

J'ai mis en place un WebServiceProvider SOAP dans JAX-WS, mais je vais avoir du mal à trouver comment obtenir le XML brut à partir d'un SOAPMessage (ou tout autre nœud) objet. Voici un exemple du code que j'ai en ce moment, et où je suis en train de saisir le code 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?
    }
}

Yat-il un moyen simple d'obtenir le code XML de la demande initiale? S'il y a un moyen d'obtenir les données XML brutes en créant un autre type de fournisseur (comme source), je serais prêt à le faire, aussi.

Était-ce utile?

La solution 3

Il se trouve que l'on peut obtenir le XML brut à l'aide du fournisseur , de cette façon:

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

J'ai fini par ne pas avoir besoin de cette solution, donc je ne l'ai pas vraiment essayé ce code moi-même - il pourrait avoir besoin de quelques ajustements pour obtenir le droit. Mais je sais que c'est le droit chemin pour aller vers le bas pour obtenir le XML brut à partir d'un service Web.

(Je ne sais pas comment faire ce travail si vous devez absolument avoir un objet SOAPMessage, mais là encore, si vous allez à manipuler le XML crudivore, pourquoi voudriez-vous utiliser un objet de niveau supérieur? )

Autres conseils

Vous pouvez essayer de cette manière.

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

Si vous avez un SOAPMessage ou SOAPMessageContext, vous pouvez utiliser un Transformer, en le convertissant en 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());

Cela prendra l'encodage en compte, afin que vos « caractères spéciaux » ne se mutilée.

pour le débogage juste but, utiliser un code de ligne -

msg.writeTo(System.out);

Si vous avez besoin de formater la chaîne XML au format 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 l'usine Transformateur: -

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 fonctionne

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

si vous avez le code client, vous avez juste besoin d'ajouter les deux lignes suivantes pour obtenir la requête XML / réponse. Ici _call est org.apache.axis.client.Call

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

Il est assez vieux fil, mais j'ai récemment eu un problème similaire. J'ai appelé un service de savon en aval, d'un service de repos, et je devais retourner la réponse XML provenant du serveur en aval est.

Alors, je fini par l'ajout d'un gestionnaire SoapMessageContext pour obtenir la réponse XML. Ensuite, le i injecté xml de réponse dans le contexte de servlet comme un 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;
            }
        }

Je l'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");

N'a pas eu la chance de le tester encore, mais cette approche doit être thread-safe car il utilise le contexte de servlet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top