简体   繁体   English

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

[英]Get value from non valid SOAP 1.1 Message with Java

My previous question was closed and marked as duplicate, but the suggested asnwer does not answer my problem, and as suggested, I'm asking a new question.之前的问题已关闭并标记为重复,但建议的 asnwer 没有回答我的问题,并且按照建议,我在问一个新问题。

Let's work with the suggested answer .让我们使用建议的答案

Here's the code:这是代码:

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>

My Fault class:我的错class:

  @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;
    }
  }

I suspected it wasn't going to work, since the elements directly inside "Fault" don't have values themselves, they have more elements inside, and also all elements are prefixed with "soap", my envelope isn't exactly structured as the one in the suggested answer.我怀疑它不会起作用,因为直接在“Fault”中的元素本身没有值,它们内部有更多元素,而且所有元素都以“soap”为前缀,我的信封结构不完全为建议答案中的那个。

But still, I couldn't fetch the "Fault" node, as an exception was thrown:但是,我仍然无法获取“故障”节点,因为抛出了异常:

unexcpected element (URI:" http://www.w3.org/2003/05/soap-envelope ", local:"Fault").意外元素(URI:“ http://www.w3.org/2003/05/soap-envelope ”,本地:“故障”)。 Expected elements are <{}Fault>预期元素是 <{}Fault>

I'm interested in getting the value of:我有兴趣获得以下价值:

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

Also, this is only for this type of error, there might be other errors, also, when the answer is positive, I get a whole different response.此外,这仅针对此类错误,可能还有其他错误,而且,当答案是肯定的时,我会得到完全不同的响应。

What I'm really insterested in is, finding a way to explore the envelope in the following way:我真正感兴趣的是,找到一种通过以下方式探索信封的方法:

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

But whatever way I'm able to reach Reason->Text will do, then I can adapt script to other bodies.但是无论我能以何种方式到达 Reason->Text 都可以,然后我可以将脚本改编为其他主体。

Thank you in advance.先感谢您。

A friend of mine who didn't want to answer here, found a solution, and even better, he found it using the way I wanted to:我的一个朋友不想在这里回答,找到了解决方案,甚至更好的是,他用我想要的方式找到了它:

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

For anyone else in the futures who stumbles upon this problem, here it is a solution:对于未来偶然发现此问题的任何其他人,这是一个解决方案:

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
      }

There you go.你是 go。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM