gpt4 book ai didi

java - 创建 QName 异常时,Opensaml unmarshallMessage 给出 opensaml 本地部分不能为 "null"

转载 作者:行者123 更新时间:2023-12-04 13:27:19 30 4
gpt4 key购买 nike

我正在使用 Spring SAML ,来自 国内流离失所者 响应 我接收颁发者作为属性 ID,所以我想在 spring saml 中接收后更改响应,所以我重写了方法 unmarshall,它将解析消息并为此更改 xml 元素。在执行此操作时,如果我在解析后直接使用 Element 来解码它正在工作,但是如果我进行 dom 操作,则会给出以下异常。我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中没有。如何在不再次转换为字符串并获取 dom 对象的情况下使其工作。

Exception in thread "main" java.lang.IllegalArgumentException: local part cannot be "null" when creating a QName
at java.xml/javax.xml.namespace.QName.<init>(QName.java:185)
at java.xml/javax.xml.namespace.QName.<init>(QName.java:129)
at org.opensaml.xml.util.XMLHelper.constructQName(XMLHelper.java:433)
at org.opensaml.xml.util.XMLHelper.getNodeQName(XMLHelper.java:171)
at org.opensaml.xml.io.UnmarshallerFactory.getUnmarshaller(UnmarshallerFactory.java:81)
at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallChildElement(AbstractXMLObjectUnmarshaller.java:334)
at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:127)
at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallChildElement(AbstractXMLObjectUnmarshaller.java:355)
at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:127)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.unmarshallMessage(unmarshallMessage.java:208)
  • 对于下面的代码,它抛出异常,如上所述。
    protected XMLObject unmarshallMessage(InputStream messageStream) throws MessageDecodingException {
    log.debug("Parsing message stream into DOM document");

    try {
    Document messageDoc = parserPool.parse(messageStream);
    Element messageElem = messageDoc.getDocumentElement();
    Element elementsByTagName = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0);
    Element issuer = messageDoc.createElement("saml2:Issuer");
    issuer.setTextContent("emIDAM");
    issuer.setAttribute("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:entity");
    log.debug("Unmarshalling message DOM");
    Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(messageElem);
    if (unmarshaller == null) {
    log.debug("Unable to unmarshall message, no unmarshaller registered for message element "
    + XMLHelper.getNodeQName(messageElem));
    throw new MessageDecodingException(
    "Unable to unmarshall message, no unmarshaller registered for message element "
    + XMLHelper.getNodeQName(messageElem));
    }
    XMLObject message = unmarshaller.unmarshall(messageElem);

    return message;
    } catch (XMLParserException e) {
    log.error("Encountered error parsing message into its DOM representation", e);
    throw new MessageDecodingException("Encountered error parsing message into its DOM representation", e);
    } catch (UnmarshallingException e) {
    log.error("Encountered error unmarshalling message from its DOM representation", e);
    throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e);
    }
    catch (Exception e) {
    log.warn("Encountered error unmarshalling message from its DOM representation --->", e);
    throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e);
    }
    }
  • 但是对于下面的代码,它工作正常,因为在这里我再次转换为字符串并创建了输入流,然后获取了用于解码的 dom。
    protected XMLObject unmarshallMessage(InputStream messageStream) throws MessageDecodingException {
    log.debug("Parsing message stream into DOM document");

    try {
    Document messageDoc = parserPool.parse(messageStream);
    Element messageElem = messageDoc.getDocumentElement();
    Element elementsByTagName = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0);
    Element issuer = messageDoc.createElement("saml2:Issuer");
    issuer.setTextContent("emIDAM");
    issuer.setAttribute("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:entity");

    //converting again to string and getting dom
    String xml = XMLHelper.nodeToString(messageElem);
    messageStream = new ByteArrayInputStream(xml.getBytes());
    messageDoc = parserPool.parse(messageStream);
    messageElem = messageDoc.getDocumentElement();


    log.debug("Unmarshalling message DOM");
    Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(messageElem);
    if (unmarshaller == null) {
    log.debug("Unable to unmarshall message, no unmarshaller registered for message element "
    + XMLHelper.getNodeQName(messageElem));
    throw new MessageDecodingException(
    "Unable to unmarshall message, no unmarshaller registered for message element "
    + XMLHelper.getNodeQName(messageElem));
    }
    XMLObject message = unmarshaller.unmarshall(messageElem);

    return message;
    } catch (XMLParserException e) {
    log.error("Encountered error parsing message into its DOM representation", e);
    throw new MessageDecodingException("Encountered error parsing message into its DOM representation", e);
    } catch (UnmarshallingException e) {
    log.error("Encountered error unmarshalling message from its DOM representation", e);
    throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e);
    }
    catch (Exception e) {
    log.warn("Encountered error unmarshalling message from its DOM representation --->", e);
    throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e);
    }
    }
  • 最佳答案

    您的问题可能与您的解析器配置有关,可能未配置为命名空间感知。
    请在初始化 parserPool 时使用类似于以下代码的内容:

    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder parserPool = documentBuilderFactory.newDocumentBuilder();
    我的猜测是第二次测试成功运行,因为在引擎盖下 XMLHelper nodeToString 正在使用 writeNode 反过来使用 LSSerializer用于执行实际的 XML 序列化。由于解析器被声明为非命名空间感知,生成的 XML 输出和相应的解析 Document将不包含 namespace 信息,或者至少,它包含的信息是由 Unmarshaller 随后执行的解析过程所包含的信息。认为合适。
    此外,请注意该问题可能与您创建新 Element 的方式有关。也因为您没有提供命名空间信息:当您使用 createElement 时,结果 Element将不包含 localName , prefix , 或 namespaceURI , 全部设置为 null .请尝试以下代码:
    Document messageDoc = parserPool.parse(messageStream);
    Element messageElem = messageDoc.getDocumentElement();
    Element assertionElem = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0);
    Element issuerElement = messageDoc.createElementNS("urn:oasis:names:tc:SAML:2.0:assertion", "saml2:Issuer");
    Attr formatAttr = messageDoc.createAttributeNS("urn:oasis:names:tc:SAML:2.0:assertion", "saml2:Format");
    formatAttr.setNodeValue("urn:oasis:names:tc:SAML:2.0:nameid-format:entity");
    issuerElement.setAttributeNode(formatAttr);
    Text text = messageDoc.createTextNode("emIDAM");
    issuerElement.appendChild(text);
    assertionElem.appendChild(issuerElement);

    关于java - 创建 QName 异常时,Opensaml unmarshallMessage 给出 opensaml 本地部分不能为 "null",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67451566/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com