Jackson XML - 从特定节点反序列化

Jackson XML - Deserialize from specific node

我是 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 设置为输入,它不会反序列化。

是否有任何配置或注释可用于实现此目的?

提前致谢,

不幸的是,目前 jackson 库不支持直接 SOAP protocol, but you can read the part you are interested with the XMLStreamReader class 直接指向相关标签:

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 class,忽略未知属性:

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