Java의 SOAPMessage에서 원시 XML 가져 오기
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();
클라이언트 코드가있는 경우 다음 두 줄을 추가하여 XML 요청 / 응답을 가져 오면됩니다. 여기 _call
있습니다org.apache.axis.client.Call
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
It is pretty old thread but recently i had a similar issue. I was calling a downstream soap service, from a rest service, and I needed to return the xml response coming from the downstream server as is.
So, i ended up adding a SoapMessageContext handler to get the XML response. Then i injected the response xml into servlet context as an attribute.
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;
}
}
Then I have retrieved the xml response string in the service layer.
ServletContext servletContext =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();
String msg = (String) servletContext.getAttribute("responseXml");
Didn't have chance to test it yet but this approach must be thread safe since it is using the servlet context.
참고URL : https://stackoverflow.com/questions/522395/getting-raw-xml-from-soapmessage-in-java
'developer tip' 카테고리의 다른 글
WPF로 로그 뷰어 구현 (0) | 2020.10.28 |
---|---|
Rails / RSpec에서 예외 발생을 테스트하는 방법은 무엇입니까? (0) | 2020.10.28 |
SQL Azure 데이터베이스의 이름을 바꾸시겠습니까? (0) | 2020.10.28 |
장고 파일 필드 삭제 (0) | 2020.10.28 |
OnGlobalLayoutListener : 지원 중단 및 호환성 (0) | 2020.10.28 |