【问题标题】:Jaxb Unmarshall SOAP EnvelopeJaxb Unmarshall SOAP 信封
【发布时间】:2020-05-27 03:26:02
【问题描述】:

我知道已经有类似的帖子,但没有一个对我有帮助。

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

}

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

谢谢。

【问题讨论】:

  • 欢迎来到 SO!问题是bairro 的xpath 是/consultaCEPResponse/return/bairro。 JAXB 字段bairro 应该嵌套在另一个代表&lt;return&gt; 标签的类中。
  • 你好亚历山德罗。谢谢!但我还是不明白,我的模型类缺少什么?
  • 这与工具soapui有什么关系?

标签: java xml soap soapui


【解决方案1】:

问题在于bairro 的xpath 是/consultaCEPResponse/return/bairro。 JAXB 字段bairro 应该嵌套在另一个代表&lt;return&gt; 标签的类中。

@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 访问

【讨论】:

  • 是的!有效。就是这样,他看不到属性,因为它在返回标签内。理解。因此,例如,如果您还有一个标签,那么 是否必须在同一段中?
  • 基本上,模型类字段结构必须镜像XML结构。我更喜欢使用静态嵌套类。如果&lt;response&gt; XPATH 是/consultaCEPResponse/return/response,那么Return 类将需要使用Response 字段(我建议使用静态嵌套类进行定义)。如果 XPATH 是 /consultaCEPResponse/response,那么 CepResponse 类将需要使用字段 Response(我建议使用静态嵌套类进行定义)。
  • 是的。非常感谢亚历山德罗!
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多