我是 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;
}
}
提前致谢!
您可以使用此代码检索 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();
}
}
IMO,您应该考虑使用工具来处理 SOAP 消息,而不是自己处理。
示例:
关于您的评论有一些话要说,所以我将我的答案放在这里。
首先,
我与 API 无关,我所做的只是发出 POST 请求...
您与 API 没有任何关系,但您向 API 发出 POST 请求。 我觉得这是一个比喻吧?...
并且没有 wsdl....
通过这个小技巧,您几乎总能获得 SOAP Web 服务的 WSDL。只需在 SOAP Web 服务 URL 末尾添加
?wsdl
。
示例:
这是网络上 SOAP Web 服务的 URL(真实的):http://www.webservicex.com/stockquote.asmx
您可以像这样获取它的 WSDL :http://www.webservicex.com/stockquote.asmx?wsdl
所以唯一的选择是解析响应
IMO,软件开发中的问题几乎总是有不止一种解决方案。
有时,我发现了这段用于将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;
}
}
public <T> T getJavaObjectFromSoapXml(String response, Class<T> clazz) {
try {
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource(response);
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(response));
xsr.nextTag();
while (!xsr.getLocalName().equalsIgnoreCase(clazz.getSimpleName())) {
log.info("TAG :{}",xsr.nextTag());
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
transformer.transform(new StAXSource(xsr), new StreamResult(stringWriter));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(stringWriter.toString())));
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
T t = (T) unmarshaller.unmarshal(document);
return t;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static <T> T unmarshallSoapResponse(final byte[] soapMessage,
Class<T> clazz) throws IOException, SOAPException, JAXBException {
SOAPMessage message = MessageFactory.newInstance().createMessage(null, new ByteArrayInputStream(soapMessage));
Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
return (T) unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());
}