将Soap XML响应转换为Object

时间:2017-11-16 15:15:32

标签: java xml soap jaxb

我不熟悉使用SOAP API的

我有来自API的肥皂回复

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<LoginResponse xmlns="http://test.org/ADMail_Service">
<LoginResult>
<ErrorMessage>Successful login</ErrorMessage>
<Status>true</Status>
</LoginResult>
</LoginResponse>
</soapenv:Body>
</soapenv:Envelope>

我正在尝试将其转换为对象。

从在线阅读文章我试图使用JAXB来做到这一点,但我的对象是空的。

以下是阅读回复的代码。我为了测试目的写了一个xml文件的响应:

try {
    XMLInputFactory xif = XMLInputFactory.newFactory();
    XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
    xsr.nextTag(); // Advance to Envelope tag

    xsr.nextTag(); // Advance to Body tag
    xsr.nextTag();
    xsr.nextTag();


    JAXBContext jc = JAXBContext.newInstance(LoginResult.class);
    Unmarshaller unmarshaller = jc.createUnmarshaller();
    JAXBElement<LoginResult> je = unmarshaller.unmarshal(xsr, LoginResult.class);

    System.out.println(je.getName());
    System.out.println(je.getValue());
} catch (XMLStreamException e) {
    e.printStackTrace();
} catch (JAXBException e) {
    e.printStackTrace();
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

LoginResult类:

public class LoginResult {
    private String errorMessage;
    private String status;

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

提前致谢!

3 个答案:

答案 0 :(得分:4)

您可以使用此代码检索POJO,并将@XmlRootElement作为标题添加到您的POJO。

(我没有测试下面的代码)

XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
        xsr.nextTag(); // Advance to Envelope tag

        xsr.nextTag(); // Advance to Body tag
        xsr.nextTag();
        xsr.nextTag();

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        StringWriter stringWriter = new StringWriter();
        transformer.transform(new StAXSource(xsr), new StreamResult(stringWriter));
        StringReader sr = new StringReader(stringWriter.toString());
        JAXBContext jaxbContext = JAXBContext.newInstance(LoginResult.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        LoginResult loginResult = (LoginResult) unmarshaller.unmarshal(sr);

编辑:

我为您找到了解决方案:

    @XmlRootElement(name = "LoginResult", namespace = "http://test.org/ADMail_Service")
@XmlAccessorType(XmlAccessType.FIELD)
public class LoginResult {
    @XmlElement(name = "ErrorMessage", namespace = "http://test.org/ADMail_Service")
    private String errorMessage;
    @XmlElement(name = "Status", namespace = "http://test.org/ADMail_Service")
    private String status;

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}


public static void main(String[] args) {
        try {
            XMLInputFactory xif = XMLInputFactory.newFactory();
            XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
            xsr.nextTag(); // Advance to Envelope tag

            xsr.nextTag(); // Advance to Body tag
            xsr.nextTag();
            xsr.nextTag();


            JAXBContext jc = JAXBContext.newInstance(LoginResult.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            JAXBElement<LoginResult> je = unmarshaller.unmarshal(xsr, LoginResult.class);

            System.out.println(je.getName());
            System.out.println(je.getValue());
            System.out.println(je.getValue().getErrorMessage());
        } catch (XMLStreamException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

答案 1 :(得分:3)

IMO,您应该考虑使用工具来处理SOAP消息,而不是自己动手

示例:

修改

您的评论有几点要说,所以我会在这里提出答案。

首先,

  

我与API无关,我所做的只是发出POST请求......

与API 无关,但您向API发出了POST请求。 我认为这是一种比喻,对吗?...

  

并且没有wsdl ....

您几乎总能通过这个小技巧获得SOAP Web服务的WSDL。只需在SOAP Web服务URL的末尾添加?wsdl

示例:

这是网络上的SOAP网络服务的URL(真实的):http://www.webservicex.com/stockquote.asmx

你可以像这样得到它的WSDL:http://www.webservicex.com/stockquote.asmx?wsdl

  

所以唯一的选择是解析响应

IMO,软件开发中的问题几乎总是不止一个解决方案。

答案 2 :(得分:0)

后来,我发现这段代码将soapxml对象解析为java对象。

private <T> T getJavaObjectFromSoapXml(String responseFilePath, Class<T> clazz) {
try {
  XMLInputFactory xif = XMLInputFactory.newFactory();
  StreamSource xml = new StreamSource(getClass().getResourceAsStream(responseFilePath));
  XMLStreamReader xsr = xif.createXMLStreamReader(xml);
  xsr.nextTag();
  while (!xsr.getLocalName().equalsIgnoreCase(clazz.getSimpleName())) {
    xsr.nextTag();
  }

  JAXBContext jc = JAXBContext.newInstance(clazz);
  Unmarshaller unmarshaller = jc.createUnmarshaller();

  JAXBElement<T> je = unmarshaller.unmarshal(xsr, clazz);
  return je.getValue();
} catch (Exception e) {
  e.printStackTrace();
  return null;
}
}