简体   繁体   English

如何将此XML SOAP响应解析为POJO?

[英]How to parse this XML SOAP response to a POJO?

I'm having a problem converting a XML SOAP return to a corresponding POJO class. 我在将XML SOAP返回到相应的POJO类时遇到问题。 The XML return looks like this: 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>

I tried to use the Jackson XMLmapper, but I can not get it to consider the 'RETURN' node as the ROOT element during deserialization. 我尝试使用Jackson XMLmapper,但我不能让它在反序列化期间将'RETURN'节点视为ROOT元素。 it considers the 'Envelope' node as ROOT node. 它将'Envelope'节点视为ROOT节点。

I need to extract just the return node and convert to my pojo class. 我只需要提取返回节点并转换为我的pojo类。

Another problem is that 'item' nodes should be part of a collection, however there is no parent node grouping these elements. 另一个问题是'item'节点应该是集合的一部分,但是没有父节点对这些元素进行分组。

Does anyone know of a parser that does deserialization of this type of xml? 有没有人知道解析这种类型的xml的解析器?

You can incorporate a streaming XML Parser (StAX) and XmlMapper in this way: 您可以通过以下方式合并流式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;
    }
}

This yields: 这会产生:

Consulta Realizada com Sucesso Consulta Realizada com Sucesso

Adapt the code as necessary, this is just to prove out how to get it to do what you need! 根据需要调整代码,这只是为了证明如何让它做你需要的!

The cleanest solution I found was using JSOUP: 我发现最干净的解决方案是使用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();

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM