JAX-WS에서 SOAP WebServiceProvider를 설정했지만 SOAPMessage (또는 모든 노드) 개체에서 원시 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을 얻는 간단한 방법이 있습니까? 다른 유형의 공급자 (예 : 소스)를 설정하여 원시 XML을 얻는 방법이 있다면 저도 그렇게 할 것입니다.
답변
이런 식으로 시도 할 수 있습니다.
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
답변
당신이있는 경우 SOAPMessage
또는 SOAPMessageContext
, 당신은을 사용할 수 있습니다 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());
이것은 인코딩을 고려하므로 “특수 문자”가 엉망이되지 않습니다.
답변
다음과 같이 Provider <Source>를 사용하여 원시 XML을 가져올 수 있습니다.
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;
}
}
이 솔루션이 필요하지 않게되었으므로 실제로이 코드를 직접 시도하지 않았습니다. 제대로 작동하려면 약간의 조정이 필요할 수 있습니다. 그러나 이것이 웹 서비스에서 원시 XML을 가져 오는 올바른 경로라는 것을 알고 있습니다.
(SOAPMessage 객체가 반드시 있어야하는 경우 어떻게 작동하는지 모르겠지만, 어쨌든 원시 XML을 처리하려는 경우 왜 더 높은 수준의 객체를 사용합니까?)
답변
디버깅 목적으로 한 줄 코드를 사용하십시오.
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();