【问题标题】:How to parse this XML SOAP response to a POJO?如何将此 XML SOAP 响应解析为 POJO?
【发布时间】:2019-05-07 23:33:18
【问题描述】:

我在将 XML SOAP 返回转换为相应的 POJO 类时遇到问题。 XML 返回如下所示:

    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
    <env:Header></env:Header>
    <env:Body>
        <ns2:teste xmlns:ns2="http://teste.com.br/">
            <retorno>
                <codigoRetorno>000</codigoRetorno>
                <descricao>Consulta Realizada com Sucesso</descricao>
                <item>
                    <a>teste</a>
                    <b>teste</b>
                    <c>teste</c>
                </item>
                <item>
                    <a>teste</a>
                    <b>teste</b>
                    <c>teste</c>
                </item>
            </retorno>
        </ns2:teste >
    </env:Body>
</env:Envelope>

我尝试使用 Jackson XMLmapper,但在反序列化过程中无法将“RETURN”节点视为 ROOT 元素。它将“信封”节点视为 ROOT 节点。

我只需要提取返回节点并转换为我的 pojo 类。

另一个问题是“item”节点应该是集合的一部分,但是没有父节点对这些元素进行分组。

有谁知道对这种类型的 xml 进行反序列化的解析器?

【问题讨论】:

    标签: java xml parsing soap jackson


    【解决方案1】:

    您可以通过这种方式合并流式 XML 解析器 (StAX) 和 XmlMapper

    import java.io.StringReader;
    
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamReader;
    
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.dataformat.xml.XmlMapper;
    
    public class Deser {
        // @formatter:off
    
        private static final String JSON = "    <env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" + 
                "    <env:Header></env:Header>\n" + 
                "    <env:Body>\n" + 
                "        <ns2:teste xmlns:ns2=\"http://teste.com.br/\">\n" + 
                "            <retorno>\n" + 
                "                <codigoRetorno>000</codigoRetorno>\n" + 
                "                <descricao>Consulta Realizada com Sucesso</descricao>\n" + 
                "                <item>\n" + 
                "                    <a>teste</a>\n" + 
                "                    <b>teste</b>\n" + 
                "                    <c>teste</c>\n" + 
                "                </item>\n" + 
                "                <item>\n" + 
                "                    <a>teste</a>\n" + 
                "                    <b>teste</b>\n" + 
                "                    <c>teste</c>\n" + 
                "                </item>\n" + 
                "            </retorno>\n" + 
                "        </ns2:teste >\n" + 
                "    </env:Body>\n" + 
                "</env:Envelope>";
    
        // @formatter:on
    
        private static final String TARGET_ELEMENT = "retorno";
    
        public static void main(String[] args) throws Exception {
            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    
            XMLInputFactory f = XMLInputFactory.newFactory();
            XMLStreamReader sr = f.createXMLStreamReader(new StringReader(JSON));
    
            while (sr.hasNext()) {
                int type = sr.next();
    
                if (type == XMLStreamReader.START_ELEMENT && TARGET_ELEMENT.equals(sr.getLocalName())) {
                    Retorno r = xmlMapper.readValue(sr, Retorno.class);
    
                    System.out.println(r.getDescricao());
                }
            }
        }
    }
    
    class Retorno {
        private int codigoRetorno;
        private String descricao;
    
        public int getCodigoRetorno() {
            return codigoRetorno;
        }
    
        public void setCodigoRetorno(int codigoRetorno) {
            this.codigoRetorno = codigoRetorno;
        }
    
        public String getDescricao() {
            return descricao;
        }
    
        public void setDescricao(String descricao) {
            this.descricao = descricao;
        }
    }
    

    这会产生:

    Consulta Realizada com Sucesso

    根据需要调整代码,这只是为了证明如何让它做你需要的!

    【讨论】:

    • 非常感谢您的提示,我不知道 StAX。但我设法使用 JSOUP 解析器以不同的方式解决它。我创建了一种提取“返回”节点的独特方法:
    【解决方案2】:

    我找到的最干净的解决方案是使用 JSOUP:

    private <T> T parseResponse(HttpEntity entity, Class<T> typeTarget) throws Exception {
    
           try {
    
               String xmlSoapResponse = EntityUtils.toString(entity, StandardCharsets.UTF_8);
               String xmlRetorno = extractXmlElement(xmlSoapResponse, "retorno");
    
               XmlMapper xmlMapper = new XmlMapper();
               xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
               xmlMapper.registerModule(new JavaTimeModule());
               return xmlMapper.readValue(xmlRetorno.toString(), typeTarget);
    
           } catch (Exception e) {
               throw new Exception("Fail during parser", e);
           }
    
       }
    
    private String extractXmlElement(String xmlString, String nodeTagNameElement) {
    
            Document document = Jsoup.parse(xmlString, "", Parser.xmlParser());
            document.outputSettings().prettyPrint(false);
            Elements retorno = document.getElementsByTag(nodeTagNameElement);
    
            return retorno.toString();
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      相关资源
      最近更新 更多