Jaxb Unmarshall SOAP конверт - PullRequest
0 голосов
/ 27 мая 2020

Я знаю, что уже есть похожий пост, но никто мне не помог.

У меня проблемы с десериализацией / демаршализацией xml.

Мой код выглядит так:

public class SoapTest {

    public static String passarXMLParaString(Document xml, int espacosIdentacao){
        try {
            //set up a transformer
            TransformerFactory transfac = TransformerFactory.newInstance();
            transfac.setAttribute("indent-number", new Integer(espacosIdentacao));
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            //create string from xml tree
            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(xml);
            trans.transform(source, result);
            String xmlString = sw.toString();
            return xmlString;
        }
        catch (TransformerException e) {
            e.printStackTrace();
            System.exit(0);
        }
        return null;
    }


    public static void main(String[] args) throws SOAPException, IOException, JAXBException {

        // consumes
        String requestSoap;
        requestSoap =  "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cli=\"http://cliente.bean.master.sigep.bsb.correios.com.br/\">\r\n" + 
                "   <soapenv:Header/>\r\n" + 
                "   <soapenv:Body>\r\n" + 
                "      <cli:consultaCEP>\r\n" + 
                "         <cep>38706400</cep>\r\n" + 
                "      </cli:consultaCEP>\r\n" + 
                "   </soapenv:Body>\r\n" + 
                "</soapenv:Envelope>";

        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
        SOAPConnection soapConnection = soapConnectionFactory.createConnection();
        String url = "https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente";
        MimeHeaders headers = new MimeHeaders();
        headers.addHeader("Content-Type", "text/xml");

        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage msg = messageFactory.createMessage(headers, (new ByteArrayInputStream(requestSoap.getBytes())));
        SOAPMessage soapResponse = soapConnection.call(msg, url);
        Document xmlRespostaARequisicao = soapResponse.getSOAPBody().getOwnerDocument();
        String xml = passarXMLParaString(xmlRespostaARequisicao, 0);
        System.out.println(passarXMLParaString(xmlRespostaARequisicao, 0));

        // returns null
        JAXBContext jc = JAXBContext.newInstance(CepResponse.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        CepResponse response = (CepResponse) unmarshaller.unmarshal(soapResponse.getSOAPBody().extractContentAsDocument().getDocumentElement());
        System.out.println(response.bairro);
    }

}

Возврат на это потребление:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:consultaCEPResponse xmlns:ns2="http://cliente.bean.master.sigep.bsb.correios.com.br/">
         <return>
            <bairro>Cidade Nova</bairro>
            <cep>38706400</cep>
            <cidade>Patos de Minas</cidade>
            <complemento2>- até 729/730</complemento2>
            <end>Avenida Presidente Tancredo Neves</end>
            <uf>MG</uf>
         </return>
      </ns2:consultaCEPResponse>
   </soap:Body>
</soap:Envelope>

Но выполнение urnmarshal возвращает мне null.

Мой класс модели:

@XmlRootElement(name = "consultaCEPResponse", namespace = "http://cliente.bean.master.sigep.bsb.correios.com.br/")
@XmlAccessorType(XmlAccessType.FIELD)
public class CepResponse {

    @XmlElement(name="bairro")
    String bairro;

}

Я пробовал другие типы демаршалла, но это не сработало. Не могли бы вы мне помочь?

Спасибо.

1 Ответ

0 голосов
/ 27 мая 2020

Проблема в том, что xpath к bairro равен /consultaCEPResponse/return/bairro. Поле JAXB bairro должно быть вложено в другой класс, представляющий тег <return>.

@XmlRootElement(name = "consultaCEPResponse", namespace = "http://cliente.bean.master.sigep.bsb.correios.com.br/")
@XmlAccessorType(XmlAccessType.FIELD)
public static class CepResponse {

    @XmlElement(name = "return")
    Return returnTag;

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Return {
        @XmlElement(name="bairro")
        String bairro;
    }
}

bairro доступно response.returnTag.bairro

...