Jaxb 解组 SOAP 信封

Jaxb Unmarshall SOAP Envelope

我知道已经有一个类似的post,但是none帮助了我。

我在反序列化/解组 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);
    }

}

本次消费的return为:

<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 return 使我无效。

我的模型class:

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

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

}

我试过其他类型的解组,但没有用。你能帮我吗?

谢谢。

问题是 bairro 的 xpath 是 /consultaCEPResponse/return/bairro。 JAXB 字段 bairro 应该嵌套在表示 <return> 标记的另一个 class 中。

@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

访问