Java Web 服务客户端 cdata 标签

标签 java xml jaxb jax-ws jdeveloper

是否可以以简单的方式在 cdata 标记内发送字符串而不转义字符? 我对此字符串使用了 @XmlCDATA 标记,当我使用 Marshaller 时,它的值会更改。但是当我想向 SoapUI 发送请求时,它没有添加这个。当我手动添加此标签时(例如在 setter 中),它会转义字符。

例如: 如果我使用编码器,我会得到:

<?xml version="1.0" encoding="UTF-8"?>
<getRequest xmlns="pl/nosd/Get">
    <ClientNumber>
        <![CDATA[<CLIENT_NUMBER>]]>
    </ClientNumber>
</getRequest>

这是正确的。

但是当我想使用服务将其发送到soapui时:

sync_Customer_Service = new Sync_Customer_Service();
Customer_PortType customer_PortType = sync_Customer_Service.getCustomer_HTTPSPort();
GetRequest  getRequest = new GetRequest();
getRequest.setClientNumber("<CLIENT_NUMBER>");
customer_PortType.get(getRequest);

我得到:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns2:GetRequestMessage xmlns="pl/nosd/Get" xmlns:ns2="http://pl/nosd/Get/xsd">
         <ClientNumber>&lt;CLIENT_NUMBER></ClientNumber>
      </ns2:GetRequestMessage>
   </S:Body>
</S:Envelope>

我添加了 jaxb.properties 文件:javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

我向 GetRequest 类添加了 @XMLCdata 注释:

public class GetRequest {
    @XmlCDATA
    @XmlElement(name = "ClientNumber", required = true)
    protected String clientNumber;
    public String getClientNumber() {
        return clientNumber;
    }
    public void setClientNumber(String value) {
        this.clientNumber = value;
    }

Service 和 portType 类由 jdeveloper 使用 Web 服务代理选项生成。

最佳答案

我找到了解决方案。解决方法并不美观,但确实有效。在客户端类中,我添加处理程序:

    BindingProvider bp = (BindingProvider)account_PortType;
    List<Handler> handlerList = bp.getBinding().getHandlerChain();
    RequestResponseHandler reqResHelper = null;
    handlerList.add(new HeaderHandler());
    bp.getBinding().setHandlerChain(handlerList);

在处理程序中,我将值替换为 Cdata 值:

    public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
          private static final String SYSTEM_ID = "pl/Customer.wsdl";
          private static final String NODE_NAME = "ClientNumber";
          public boolean handleMessage(SOAPMessageContext context) {
     try{
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            Object o = context.get(LogicalMessageContext.WSDL_DESCRIPTION);
            org.xml.sax.InputSource is = (org.xml.sax.InputSource)o;
            if(is.getSystemId().contains(SYSTEM_ID)){
                SOAPMessage message = context.getMessage();
                SOAPBody body = message.getSOAPBody();
                Node e =getNode(body.getChildNodes());
                CDATASection cdataSection = message.getSOAPPart().createCDATASection(e.getFirstChild().getNodeValue());
                e.replaceChild(cdataSection, e.getFirstChild());
            }
        } 
    }catch(Exception e){
        //TODO logować
    } 

    return true;

}

public Node getNode(NodeList a){
    if(a!=null&&a.getLength()>0){
        for(int i = 0;i<a.getLength();i++){
            Node b = a.item(i);
            if(b.getNodeName()!=null && b.getNodeName().contains(NODE_NAME)){
                return b;
            }
            Node node = getNode(b.getChildNodes());
            if(node!=null){
                return node;
            }
        }
    }

    return null;
}

在soapui中我们看到:

<ns6:ClientNumber>
  <![CDATA[data]]>
</ns6:ClientNumber>

关于Java Web 服务客户端 cdata 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38405083/

相关文章:

php - 格式化 xml 字符串

java - 解码 soap 类转换异常

java - 如何将txt文件读取到android项目文件夹中

java - 在元素上设置命名空间属性

c# - DataContractSerializer - 命名空间问题

c# - 获取 XML 文件的版本而不从服务器下载它

java - 推土机 - 测绘集合

java - 如何将通用 JAXBElement 作为输入

java - 更新准备好的语句未提交

Java Print Stream 打印空格