我在JAX-WS中设置了一个SOAP WebServiceProvider,但是我无法弄清楚如何从SOAPMessage(或任何Node)对象中获取原始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?如果有办法通过设置不同类型的Provider(例如Source)来获取原始XML,我也愿意这样做。
答案 0 :(得分:142)
你可以这样试试。
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
答案 1 :(得分:18)
如果您有SOAPMessage
或SOAPMessageContext
,则可以使用Transformer
,通过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());
这将考虑编码,因此您的“特殊字符”不会被破坏。
答案 2 :(得分:11)
事实证明,通过使用Provider&lt; Source&gt;,可以通过以下方式获取原始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;
}
}
我最终不需要这个解决方案,所以我自己并没有真正尝试过这个代码 - 可能需要进行一些调整才能做到正确。但我知道这是从Web服务获取原始XML的正确途径。
(如果你绝对必须拥有一个SOAPMessage对象,我不知道如何使这个工作,但是如果你将要处理原始XML,那么为什么你会使用更高级别的对象? )
答案 3 :(得分:11)
仅用于调试目的,使用一行代码 -
msg.writeTo(System.out);
答案 4 :(得分:6)
如果需要将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")));
答案 5 :(得分:4)
使用变压器工厂: -
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();
}
答案 6 :(得分:2)
这是有效的
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();
答案 7 :(得分:0)
如果您有客户端代码,那么您只需添加以下两行来获取XML请求/响应。此处_call
为org.apache.axis.client.Call
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
答案 8 :(得分:0)
这是一个很老的话题,但是最近我遇到了类似的问题。我正在从rest服务调用下游肥皂服务,我需要按原样返回来自下游服务器的xml响应。
因此,我最终添加了一个SoapMessageContext处理程序以获取XML响应。然后,将响应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");
还没有机会对其进行测试,但是这种方法必须是线程安全的,因为它正在使用servlet上下文。