使用Java从无效的SOAP 1.1消息中获取值



我之前的问题被关闭并标记为重复,但建议的asnwer没有回答我的问题,正如建议的那样,我正在问一个新问题。

让我们按照建议的答案来做吧。

这是代码:

String strMsg = "<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">" +
" <soap:Header>" +
"  <context xmlns="urn:zimbra"/>" +
" </soap:Header>" +
" <soap:Body>" +
"  <soap:Fault>" +
"   <soap:Code>" +
"    <soap:Value>soap:Sender</soap:Value>" +
"   </soap:Code>" +
"   <soap:Reason>" +
"    <soap:Text>no valid authtoken present</soap:Text>" +
"   </soap:Reason>" +
"   <soap:Detail>" +
"    <Error xmlns="urn:zimbra">" +
"     <Code>service.AUTH_REQUIRED</Code>" +
"     <Trace>qtp1027591600-6073:1588614639199:4eacbd0257a457b6</Trace>" +
"    </Error>" +
"   </soap:Detail>" +
"  </soap:Fault>" +
" </soap:Body>" +
"</soap:Envelope>";
InputStream is = new ByteArrayInputStream(strMsg.getBytes());
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(is);
//Envelope
xsr.nextTag();
QName name = xsr.getName();
//Header
xsr.nextTag();
name = xsr.getName();
//Context
xsr.nextTag();
name = xsr.getName();
//Context again
xsr.nextTag();
name = xsr.getName();
//Header again
xsr.nextTag();
name = xsr.getName();
//Body
xsr.nextTag();
name = xsr.getName();
//Fault
xsr.nextTag();
name = xsr.getName();
/* IM COMMENTING THE FOLLOWING CODE BECAUSE I'M INTERESTED IN THE FAULT CONTENT
* AND EVEN IF IT TRY TO GO DEEPER I CAN'T GO PASS "VALUE" NODE
*
//Code
xsr.nextTag();
name = xsr.getName();
//Value
xsr.nextTag();
name = xsr.getName();
//throws exception, no more elements for some reason
xsr.nextTag();
name = xsr.getName();
*/
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(Fault.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Fault fault = (Fault) unmarshaller.unmarshal(sr); //THROWS EXCEPTION
//"unexcpected element (URI:"http://www.w3.org/2003/05/soap-envelope", local:"Fault"). Expected elements are <{}Fault>

我的故障类别:

@XmlRootElement(name = "Fault")
@XmlAccessorType(XmlAccessType.FIELD)
public static class Fault {
@XmlElement(name = "Code")
private String code;
@XmlElement(name = "Reason")
private String reason;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}

我怀疑它不会起作用,因为直接在"Fault"内部的元素本身没有值,它们内部有更多的元素,而且所有元素都以"soap"为前缀,所以我的信封的结构与建议答案中的信封不完全一样。

但是,我仍然无法获取"Fault"节点,因为抛出了一个异常:

未期望的元素(URI:"http://www.w3.org/2003/05/soap-envelope",local:"Fault"(。预期元素为<{}Fault>

我对获得的价值感兴趣

<soap:Text>no valid authtoken present</soap:Text>"

此外,这只是针对这种类型的错误,可能还有其他错误,而且,当答案是肯定的时,我会得到完全不同的回答。

我真正感兴趣的是,找到一种以以下方式探索信封的方法:

//pseudo code
(envelope->body->fault->reason->text != null) {reasonText = envelope->body->fault->reason->text)

但无论我能以何种方式到达Reason->Text,我都可以将脚本改编为其他主体。

提前谢谢。

我的一个朋友不想在这里回答,他找到了一个解决方案,甚至更好的是,他用我想要的方式找到了它:

//pseudo code
(envelope->body->fault->reason->text != null) {reasonText = envelope->body->fault->reason->text)

对于未来任何一个偶然发现这个问题的人来说,这里有一个解决方案:

String strMsg = "<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">" +
" <soap:Header>" +
"  <context xmlns="urn:zimbra"/>" +
" </soap:Header>" +
" <soap:Body>" +
"  <soap:Fault>" +
"   <soap:Code>" +
"    <soap:Value>soap:Sender</soap:Value>" +
"   </soap:Code>" +
"   <soap:Reason>" +
"    <soap:Text>no valid authtoken present</soap:Text>" +
"   </soap:Reason>" +
"   <soap:Detail>" +
"    <Error xmlns="urn:zimbra">" +
"     <Code>service.AUTH_REQUIRED</Code>" +
"     <Trace>qtp1027591600-6073:1588614639199:4eacbd0257a457b6</Trace>" +
"    </Error>" +
"   </soap:Detail>" +
"  </soap:Fault>" +
" </soap:Body>" +
"</soap:Envelope>";
strMsg = strMsg.replaceAll("soap:",""); //Had to replace soap:, not fancy but it works.
is = new ByteArrayInputStream(strMsg.getBytes());
InputSource xml = new InputSource(is);
XPath xPath = XPathFactory.newInstance().newXPath();
Object exprEval = xPath.compile("/Envelope/Body/Fault/Reason/Text/text()").evaluate(xml, XPathConstants.STRING);
if ( exprEval != null ) {
System.out.println( "Fault reason text: " + exprEval );
// This prints what's expected:
// Fault reason text: no valid authtoken present
}

给你。

相关内容

  • 没有找到相关文章

最新更新