是的,我知道这个问题的一般形式一次又一次被问到。但是,我找不到任何帮助我解决问题的方法,所以发布了这个问题,特别是我的问题。
我试图弄清楚为什么我得到一个SAXParseException
(Content is not allowed in prolog.
),因为OpenSAML库试图解析一些XML。我发现最有用的提示指向文件开头的错误BOM,但没有类似的东西。我还编写了一个快速而肮脏的C#.NET例程,将整个文件作为一个字节数组读取,迭代它并告诉我它们是否为> = 0x80(它没有找到)。 XML标记为utf-8。我希望有人可以就可能出现的问题向我提供一些见解。
XML文件的初始部分(作为十六进制转储)是(注意使用0A
作为换行符;完全删除换行符没有明显效果):
000000000 3C 3F 78 6D 6C 20 76 65-72 73 69 6F 6E 3D 22 31 |<?xml version="1|
000000010 2E 30 22 20 65 6E 63 6F-64 69 6E 67 3D 22 55 54 |.0" encoding="UT|
000000020 46 2D 38 22 3F 3E 0A 3C-6D 64 3A 45 6E 74 69 74 |F-8"?>.<md:Entit|
000000030 79 44 65 73 63 72 69 70-74 6F 72 20 78 6D 6C 6E |yDescriptor xmln|
000000040 73 3A 6D 64 3D 22 75 72-6E 3A 6F 61 73 69 73 3A |s:md="urn:oasis:|
000000050 6E 61 6D 65 73 3A 74 63-3A 53 41 4D 4C 3A 32 2E |names:tc:SAML:2.|
000000060 30 3A 6D 65 74 61 64 61-74 61 22 20 |0:metadata" |
根本原因异常的堆栈跟踪是:
org.xml.sax.SAXParseException: Content is not allowed in prolog.
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
org.opensaml.xml.parse.BasicParserPool$DocumentBuilderProxy.parse(BasicParserPool.java:665)
my.Unmarshaller.unmarshall(Unmarshaller.java:39)
... internal calls omitted for brevity ...
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
尝试进行解组的代码是(在此处输入完全限定的名称;希望我不会遗漏一些重要的内容):
package my;
public class Unmarshaller {
protected static org.opensaml.xml.parse.ParserPool parserPool;
static {
org.opensaml.xml.parse.BasicParserPool _parserPool;
_parserPool = new org.opensaml.xml.parse.BasicParserPool();
_parserPool.setNamespaceAware(true);
Unmarshaller.parserPool = _parserPool;
}
public Unmarshaller() {
try {
org.opensaml.DefaultBootstrap.bootstrap();
} catch (org.opensaml.xml.ConfigurationException e) {
throw new java.lang.RuntimeException (e);
}
}
public Object unmarshall(String xml)
throws org.opensaml.xml.io.UnmarshallingException {
assert xml != null;
assert !xml.isEmpty();
assert Unmarshaller.parserPool != null;
org.w3c.dom.Document doc;
try {
doc =
(parserPool.getBuilder())
.parse( // <<<====== line 39 in original source code is here
new org.xml.sax.InputSource(
new java.io.StringReader(xml)
)
);
} catch (org.xml.sax.SAXException e) {
throw new org.opensaml.xml.io.UnmarshallingException(e);
} catch (java.io.IOException e) {
throw new org.opensaml.xml.io.UnmarshallingException(e);
} catch (org.opensaml.xml.parse.XMLParserException e) {
throw new org.opensaml.xml.io.UnmarshallingException(e);
}
// ... remainder of function omitted for brevity ...
}
}
答案 0 :(得分:6)
我看不到文件转储中的XML片段有什么问题。当你说XML文件验证时,我相信你。
但是,您没有提供水密证据证明解析器看到的 有效。例如:
您可能正在尝试将另一个文件解析为已转储的文件。 (已知这些事情会发生......)。
或者,将XML转换为然后解析的String的方式可能有问题。
尝试转储提供解析器源流的String的前几行。
答案 1 :(得分:0)
有些情况下SAMLReponses是Base64编码的,消费者(Controller或Servlets)需要解码以解决“prolog中不允许内容”的问题
以下是代码段:
// code snippet
String responseMessage = httpServletRequest.getParameter("SAMLResponse");
byte[] decoded = Base64.decode(responseMessage);
ByteArrayInputStream is = new ByteArrayInputStream(decoded);
// write your xml parsing logic here.