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

时间:2016-08-25 11:48:29

标签: java web-services jax-ws cdata

我有一个使用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);

我尝试在@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;
    }
}

知道如何存档吗? 感谢

1 个答案:

答案 0 :(得分: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。