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を取得する方法があれば、私はあまりにも、それを行うことをいとわないと思います。
解決 3
これは、1つは、このように、プロバイダ<ソース>を使用して、生の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を取得するためにダウンする正しい道である知っています。
(あなたがとにかく生のXMLを処理するつもりなら、私はなぜあなたがより高いレベルのオブジェクトを使用することになり、その後、再び、あなたは絶対にSOAPMessageオブジェクトを持っている必要があります場合は、この作業を行う方法がわからないんだけど? )
他のヒント
あなたは、このようにしてみてください可能性があります。
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());
あなたが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());
このアカウントへのエンコードがかかりますので、あなたの「特殊文字は」マングルされ得ることはありません。
ちょうど目的をデバッグするために、1行のコードを使用する -
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")));
トランスファクトリーを使用した: -
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要求/応答を取得するには、以下の2行を追加する必要があります。ここで_call
がorg.apache.axis.client.Call
される
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
これはかなり古いスレッドですが、最近、私は同様の問題がありました。私は、RESTサービスから、下流のSOAPサービスを呼んでいた、と私はあるとして、下流サーバーからXML応答を返すために必要な。
だから、私は、XML応答を取得するためにSoapMessageContextハンドラを追加することになりました。私は属性としてサーブレットコンテキストに応答XMLを注入します。
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");
まだそれをテストする機会を持っていなかったが、それはサーブレットコンテキストを使用しているので、このアプローチは、スレッドセーフである必要があります。