仅使用 JAX-WS 在请求的字符串参数上添加 CDATA

Add CDATA on request's string parameter using only JAX-WS

我有一个使用 CXF 生成的 jax-ws 客户端

请求有一个包含 xml 的字符串参数 (MGRequest),一切正常,但生成的请求是这样的:

<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);

我尝试在 @WebParam 之前添加 @XmlJavaTypeAdapter(CDataAdapter.class) 但结果是:

<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;
    }
}

知道如何存档吗? 谢谢

经过一个晚上的工作,我找到了解决方案: 像这样向客户端添加 javax.xml.ws.handler.Handler

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

我的 HandlerFactory 构建处理程序的位置:

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;
  }
}

这是一个简单的 class,我只有一个带有文本的标签,但在更复杂的情况下,您可以在 DOM.

中采取必要的操作