【问题标题】:Jackson XML - Deserialize from specific nodeJackson XML - 从特定节点反序列化
【发布时间】:2021-12-15 21:18:24
【问题描述】:

我是 Jackson XML 的新手,我想做以下事情:

  1. 这是我想转换为 Java DTO 的 XML:

     <s:Envelope
         xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
         <s:Body>
             <cotacaoTaxaCambioResponse
                 xmlns="http://tempuri.org/">
                 <cotacaoTaxaCambioResult
                     xmlns:a="http://schemas.datacontract.org/2004/07/Exchange"
                     xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                     <a:TaxasCambio>
                         <a:CotacaoTaxaCambio>
                             <a:CLIENTEC>0</a:CLIENTEC>
                             <a:CLIENTEV>0</a:CLIENTEV>
                             <a:COMERCIALC>0</a:COMERCIALC>
                             <a:COMERCIALV>30</a:COMERCIALV>
                             <a:DATA>2021-12-15T00:00:00</a:DATA>
                             <a:HORARIO>1027</a:HORARIO>
                             <a:MOEDA>978</a:MOEDA>
                             <a:PARIDADEC>1</a:PARIDADEC>
                             <a:PARIDADEV>1</a:PARIDADEV>
                             <a:TURISMOC>0</a:TURISMOC>
                             <a:TURISMOV>30</a:TURISMOV>
                         </a:CotacaoTaxaCambio>
                     </a:TaxasCambio>
                     <a:serviceStatus>
                         <a:CODRETORNO>0</a:CODRETORNO>
                         <a:MENSAGEM>Sucesso</a:MENSAGEM>
                         <a:MENSAGEMEN>OK</a:MENSAGEMEN>
                         <a:NRREFERENCE>0</a:NRREFERENCE>
                     </a:serviceStatus>
                 </cotacaoTaxaCambioResult>
             </cotacaoTaxaCambioResponse>
         </s:Body>
     </s:Envelope>
    
  2. 我需要的信息是 a:CotacaoTaxaCambio 节点的属性。

  3. 创建了这个 DTO

         @JacksonXmlRootElement(localName = "a:CotacaoTaxaCambio")
         public class CotacaoResDTO {
    
             @JacksonXmlProperty(localName = "a:DATA")
             private String data;
    
             @JacksonXmlProperty(localName = "a:HORARIO")
             private String hora;
    
             @JacksonXmlProperty(localName = "a:MOEDA")
             private String codMoeda;
    
             @JacksonXmlProperty(localName = "a:COMERCIALV")
             private Double valorComercial;
    
             @JacksonXmlProperty(localName = "a:TURISMOV")
             private Double valorTurismo;
         }
    
  4. 如果我将此子集设置为输入,它确实有效:

                 <a:CotacaoTaxaCambio>
                     <a:CLIENTEC>0</a:CLIENTEC>
                     <a:CLIENTEV>0</a:CLIENTEV>
                     <a:COMERCIALC>0</a:COMERCIALC>
                     <a:COMERCIALV>30</a:COMERCIALV>
                     <a:DATA>2021-12-15T00:00:00</a:DATA>
                     <a:HORARIO>1027</a:HORARIO>
                     <a:MOEDA>978</a:MOEDA>
                     <a:PARIDADEC>1</a:PARIDADEC>
                     <a:PARIDADEV>1</a:PARIDADEV>
                     <a:TURISMOC>0</a:TURISMOC>
                     <a:TURISMOV>30</a:TURISMOV>
                 </a:CotacaoTaxaCambio>
    

但如果我将完整的 xml 设置为输入,它不会反序列化。

我可以使用任何配置或注释来存档吗?

提前致谢,

【问题讨论】:

    标签: java jackson jackson-dataformat-xml


    【解决方案1】:

    很遗憾,目前jackson库不直接支持SOAP协议,但是你可以通过XMLStreamReader类直接指向所涉及的标签来阅读你感兴趣的部分:

    XMLInputFactory f = XMLInputFactory.newFactory();
    XMLStreamReader sr = f.createXMLStreamReader(new FileInputStream(xml));
    XmlMapper mapper = new XmlMapper();
    sr.nextTag();
    while (!sr.getLocalName().equals("CotacaoTaxaCambio")) {
       sr.nextTag();
    }
    CotacaoResDTO value = mapper.readValue(sr, CotacaoResDTO.class);
    sr.close();
    

    您还必须修改您的 CotacaoResDTO 类,忽略未知属性:

    @JsonIgnoreProperties(ignoreUnknown = true)
    public class CotacaoResDTO {
    
        @JacksonXmlProperty(localName = "DATA")
        private String data;
    
        @JacksonXmlProperty(localName = "HORARIO")
        private String hora;
    
        @JacksonXmlProperty(localName = "MOEDA")
        private String codMoeda;
    
        @JacksonXmlProperty(localName = "COMERCIALV")
        private Double valorComercial;
    
        @JacksonXmlProperty(localName = "TURISMOV")
        private Double valorTurismo;
    }
    

    【讨论】:

    • 太棒了!它有效,最后我所做的是将 XML 转换为 JSON 以使用 JsonNode 导航,这是一个中间解决方案,因为在你回答之前我没有找到任何其他解决方案。谢谢!
    • @EmilioNumazaki 不客气 :-) 是的,这正是您无需转换为 json 的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 2020-05-15
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多