2009-02-06 4 views
58

Я установил SOAP WebServiceProvider в JAX-WS, но мне трудно понять, как получить необработанный XML из объекта SOAPMessage (или любого узла). Вот пример кода, я получил прямо сейчас, и где я пытаюсь захватить XML:Получение Raw XML из SOAPMessage в Java

@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), я тоже захочу сделать это.

ответ

11

Оказывается, что можно получить необработанный XML с помощью поставщика < 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 в любом случае, почему бы вам использовать объект более высокого уровня ?)

+0

'StringWriter' является хорошей альтернативой' 'ByteArrayOutputStream' + StreamResult' комбинации, если вы хотите, чтобы XML как 'String' с правильной кодировкой – artbristol

131

Вы можете попробовать таким образом.

SOAPMessage msg = messageContext.getMessage(); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
msg.writeTo(out); 
String strMsg = new String(out.toByteArray()); 
+4

Это потрясающе. – user85155

+3

Это не учитывает кодировку символов – artbristol

+0

Будет ли она потреблять много памяти с чем-то вроде построения объектов DOM или тому подобного? Или это действительно даст исходную строку из ответа HTTP без внутреннего анализа xml? – Ruslan

4

Если вам нужно форматировать 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"))); 
14

Если у вас есть 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()); 

Это займет кодировку, поэтому ваши «специальные символы» не будут искалечены.

+0

Предоставлена ​​ли поглощение памяти? – lospejos

8

для просто отладки цели, использовать один код строки -

msg.writeTo(System.out);

+0

OP не обязательно отлаживает систему.(что не всегда удобно доступно для веб-сервера) - ему может потребоваться отправить исходный XML через сокет, сохранить его где-нибудь или рассчитать его статистику. – hexafraction

+1

просто рассказывал о варианте, ничего больше. спасибо –

+0

Вы можете легко написать 'ByteArrayOutputStream' конвертировать в' String' ... кажется мне легко – vikingsteve

0

, если у вас есть код клиента, то вам просто необходимо добавить следующие две строки, чтобы получить запрос XML/ответ. Здесь _call является org.apache.axis.client.Call

String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString(); 
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString(); 
3

Использование 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(); 
    } 
1

это работает

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(); 
+0

Еще немного объяснений вместо дампа кода было бы хорошо. – Raidri

+0

Никаких объяснений не требуется. –

Смежные вопросы