Я установил SOAP WebServiceProvider в JAX-WS, но мне сложно понять, как получить необработанный XML из объекта SOAPMessage (или любого узла). Вот пример кода, который у меня есть прямо сейчас, и из которого я пытаюсь получить 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, установив другой тип поставщика (например, Source), я бы тоже хотел это сделать.
Если у вас есть
SOAPMessage
илиSOAPMessageContext
, вы можете использовать aTransformer
, преобразовав его в переходное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());
При этом будет принята во внимание кодировка, поэтому ваши «специальные символы» не будут искажены.
источник
Оказывается, можно получить необработанный XML с помощью Provider <Source> следующим образом:
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, зачем вам использовать объект более высокого уровня?)
источник
StringWriter
- хорошая альтернатива комбинацииByteArrayOutputStream
+StreamResult
, если вы хотите, чтобы XML былString
с правильной кодировкойпросто для целей отладки используйте однострочный код -
msg.writeTo(System.out);
источник
ByteArrayOutputStream
обращенного вString
... мне это кажется легкимЕсли вам нужно отформатировать строку 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
источник
Это довольно старый поток, но недавно у меня была аналогичная проблема. Я звонил в подчиненную службу мыла из службы отдыха, и мне нужно было вернуть xml-ответ, приходящий с нижестоящего сервера, как есть.
Итак, я добавил обработчик SoapMessageContext, чтобы получить ответ XML. Затем я ввел ответ 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");
Еще не было возможности протестировать его, но этот подход должен быть потокобезопасным, поскольку он использует контекст сервлета.
источник