2016-08-25 11 views
1

У меня есть клиент JAX-WS ganerated с CXFДобавить CDATA по параметру строки запроса, используя только JAX-WS

Запроса есть строка-параметр (MGRequest), который содержит XML, все работы, но сгенерированный запрос как это:

<S:Body> 
    <ns5:MGRequest>&lt;mytag&gt;hello&lt;/mytag&gt;</ns5:MGRequest> 
</S:Body> 

Мне нужно создать тело, как:

<S:Body> 
    <ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest> 
</S:Body> 

(потому что я не могу управлять сервером ..)

Клиент как стандартный JAX-WS:

@WebService(name = "ServiceSoap") 
@XmlSeeAlso({ ObjectFactory.class}) 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) 
public interface ServiceSoap { 

    @WebMethod(operationName = "ProcessMessage") 
    @WebResult(name = "MGResponse") 
    public String processMessage(
     @WebParam(partName = "input", name = "MGRequest") String input); 
} 

И я называю так:

Service client = new Service(url); 
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler())); 

ServiceSoap service = client.getServiceSoap(); 

String msgToSend = JaxbUtil.jaxbObjToString(xmlObj, false); 
String response = service.processMessage(msgToSend); 

Я попытался добавить @XmlJavaTypeAdapter(CDataAdapter.class) до @WebParam, но результат был:

<S:Body> 
    <ns5:MGRequest>&lt;![CDATA[&lt;mytag&gt;hello&lt;/mytag&gt;]]&gt;</ns5:MGRequest> 
</S:Body> 

Где CDataAdapter:

public class CDataAdapter extends XmlAdapter<String, String> { 

    @Override 
    public String marshal(String v) throws Exception { 
     return "<![CDATA[" + v + "]]>"; 
    } 

    @Override 
    public String unmarshal(String v) throws Exception { 
     return v; 
    } 
} 

Любая идея, как это сделать? Благодаря

ответ

2

После рабочего ночи я нашел решение: добавление javax.xml.ws.handler.Handler к клиенту, как это:

client.setHandlerResolver(HandlerFactory.build(new LoggerHandler(), new CDataHandler())); 

где мой HandlerFactory построить Handler:

public static HandlerResolver build(final Handler... handlers) { 

    return new HandlerResolver() { 
     @Override 
     public List<Handler> getHandlerChain(PortInfo portInfo) { 
     List<Handler> handlerChain = new ArrayList<Handler>(); 

     if (handlers != null) { 
      for (Handler handler : handlers) { 
      handlerChain.add(handler); 
      } 
     } 
     return handlerChain; 
     } 
    }; 
    } 

import javax.xml.namespace.QName; 
import javax.xml.soap.Node; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPHandler; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

public class CDataHandler implements SOAPHandler<SOAPMessageContext> { 

    @Override 
    public void close(MessageContext context) { 
    } 

    @Override 
    public boolean handleMessage(SOAPMessageContext soapMessage) { 
    try { 
     SOAPMessage message = soapMessage.getMessage(); 
     boolean isOutboundMessage = (Boolean) soapMessage 
      .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

     // is a request? 
     if (isOutboundMessage) { 
     // build a CDATA NODE with the text in the root tag 
     Node cddata = (Node) message.getSOAPPart().createCDATASection(
      message.getSOAPBody().getFirstChild().getTextContent()); 

     // add the CDATA's node at soap message 
     message.getSOAPBody().getFirstChild().appendChild(cddata); 

     // remove the text tag with the raw text that will be escaped 
     message.getSOAPBody().getFirstChild() 
      .removeChild(message.getSOAPBody().getFirstChild().getFirstChild()); 

     } 

    } catch (Exception ex) { 
     // fail 
    } 
    return true; 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext soapMessage) { 
    return true; 
    } 

    @Override 
    public Set<QName> getHeaders() { 
    return Collections.EMPTY_SET; 
    } 
} 

Это простой класс, у меня был только один тег с текст, но в более сложном сценарии вы можете предпринять необходимые действия для навигации по DOM.

+1

Вышеупомянутое решение, которое нужно обработать, необходимо добавить «message.saveChanges();» в функции сообщения сообщения handleMessage. См. Https://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/ –