문제

JAX-WS에 SOAP WebServiceProvider를 설정했지만 SOAPMessage (또는 모든 노드) 객체에서 RAW XML을 얻는 방법을 알아내는 데 어려움이 있습니다. 다음은 내가 지금 가지고있는 코드의 샘플과 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?
    }
}

원래 요청의 XML을 얻는 간단한 방법이 있습니까? 다른 유형의 공급자 (예 : 소스)를 설정하여 RAW XML을 얻는 방법이 있다면 기꺼이 그렇게 할 것입니다.

도움이 되었습니까?

해결책 3

공급자를 사용하여 RAW XML을 얻을 수 있다는 것이 밝혀졌습니다.u003CSource> , 이런 식으로:

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

결국이 솔루션이 필요하지 않아서 실제로이 코드를 직접 시도하지 않았습니다. 제대로하기 위해서는 약간의 조정이 필요할 수 있습니다. 그러나 나는 이것이 웹 서비스에서 RAW XML을 얻기 위해 내려가는 올바른 길이라는 것을 알고 있습니다.

(SoapMessage 객체가 절대적으로 있어야한다면이 작업을 수행하는 방법은 확실하지 않지만 다시, Raw XML을 어쨌든 처리하려는 경우 왜 더 높은 수준의 객체를 사용하겠습니까?)

다른 팁

이런 식으로 시도 할 수 있습니다.

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

당신이있는 경우 SOAPMessage 또는 SOAPMessageContext, 당신은 a를 사용할 수 있습니다 Transformer, 그것을 a로 변환함으로써 Source ~을 통해 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());

인코딩이 고려되므로 "특수 문자"가 엉망이되지 않습니다.

디버깅 목적으로 원하시면 한 줄 코드를 사용하십시오.

msg.writeTo(System.out);

XML 문자열을 XML로 서식 해야하는 경우 다음을 시도하십시오.

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

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

이것은 작동합니다

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

클라이언트 코드가있는 경우 XML 요청/응답을 얻으려면 다음 두 줄을 추가하면됩니다. 여기 _call ~이다 org.apache.axis.client.Call

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

꽤 오래된 실이지만 최근에는 비슷한 문제가있었습니다. 휴식 서비스에서 다운 스트림 비누 서비스를 호출했으며 다운 스트림 서버에서 오는 XML 응답을 그대로 반환해야했습니다.

그래서 XML 응답을 얻기 위해 SoapMessageContext 핸들러를 추가했습니다. 그런 다음 응답 XML을 Servlet 컨텍스트에 속성으로 주입했습니다.

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

그런 다음 서비스 계층에서 XML 응답 문자열을 검색했습니다.

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

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

아직 테스트 할 기회가 없었지만이 접근법은 서블릿 컨텍스트를 사용하기 때문에 스레드 안전해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top