为什么我会收到文件过早结束错误?

问题描述 投票:0回答:9

我正在尝试解析一个

XML response
,但我失败得很惨。我一开始以为
xml
只是没有在响应中返回,因此我编写了下面的代码,并直接链接到我的
xml
在线文件。我可以毫无问题地将
XML
打印到屏幕上。但是,当我调用解析方法时,我得到文件过早结束。

如果我直接传递 URL 就可以了:

  • builder.parse("");

但是当我传递InputStream时失败:

  • builder.parse(connection.getInputStream());

      try {
        URL url = new URL(xml);
        URLConnection uc =  url.openConnection();
        HttpURLConnection  connection = (HttpURLConnection )uc;
    
        connection.setDoInput(true);
        connection.setDoOutput(true);
    
        InputStream instream;
        InputSource source;
        //get XML from InputStream
        if(connection.getResponseCode()>= 200){
            connection.connect();       
            instream = connection.getInputStream();         
            parseDoc(instream);     
        }
        else{
            instream = connection.getErrorStream();
        }
    
    
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    
    
     static void parseDoc(InputStream instream) throws ParserConfigurationException,
     SAXException, IOException{
    
    
      BufferedReader buff_read = new BufferedReader(new InputStreamReader(instream,"UTF-8"));
        String  inputLine = null;
    
        while((inputLine = buff_read.readLine())!= null){
            System.out.println(inputLine);
        }
    
      DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
      factory.isIgnoringElementContentWhitespace();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(instream);
    }
    

我遇到的错误:

    [Fatal Error] :1:1: Premature end of file.
org.xml.sax.SAXParseException: Premature end of file.
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
    at com.ameba.api.network.MainApp.parseDoc(MainApp.java:78)
    at com.ameba.api.network.MainApp.main(MainApp.java:41)
java xml httpurlconnection
9个回答
40
投票

当你这样做时,

while((inputLine = buff_read.readLine())!= null){
        System.out.println(inputLine);
    }

您消耗了 instream 中的所有内容,因此 instream 是空的。 现在当尝试这样做时,

Document doc = builder.parse(instream);

解析将会失败,因为你传递给它的是一个空流。


6
投票

您收到错误是因为 SAXBuilder 不够智能,无法处理“空白状态”。因此,它至少会查找一个

<xml ..>
声明,当这导致无数据响应时,它会创建您看到的异常,而不是报告空状态。


4
投票

对于那些到达此帖子寻求答案的人:

发生这种情况主要是因为 DOM 解析器正在消耗的

InputStream
是空的

所以我遇到的情况,可能有两种情况:

  1. 您传递给解析器的
    InputStream
    已被使用,因此被清空。
  2. File
    或您创建
    InputStream
    的任何内容可能是空文件或字符串或其他任何内容。空虚可能是导致问题的原因。所以你需要检查你的
    InputStream
    的来源。

1
投票

我遇到了同样的错误,并且可以通过记录异常轻松找到问题所在:

documentBuilder.setErrorHandler(new ErrorHandler() {
    @Override
    public void warning(SAXParseException exception) throws SAXException {
        log.warn(exception.getMessage());
    }

    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        log.error("Fatal error ", exception);
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        log.error("Exception ", exception);
    }
});

或者,您可以

throw
catch
处理条目,而不是记录错误,这样您就可以打印条目本身以获得有关错误的更好指示。


1
投票

我通过将源提要从 http://www.news18.com/rss/politics.xml 转换为 https://www.news18.com/rss/politics.xml

解决了该问题

下面的 http 代码创建了一个空文件,这导致了问题

    String feedUrl = "https://www.news18.com/rss/politics.xml"; 
    File feedXmlFile = null;

    try {
    feedXmlFile =new File("C://opinionpoll/newsFeed.xml");
    FileUtils.copyURLToFile(new URL(feedUrl),feedXmlFile);


          DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
          DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
          Document doc = dBuilder.parse(feedXmlFile);

1
投票

输入流只使用一次,不要多次使用 执行 inputstream.close()


0
投票

<?xml version="1.0" encoding="UTF-8"?>

确保在顶层正确插入标题,并且它不应指向 XML 文件中的任何后代。


0
投票

感谢 @Sai 研究和分享此分析。


就我而言,这是因为

checkstyle
失败。

构建的控制台输出看起来像这样

BUILD FAILED
/Users/username/buildtool-pkg-cache/packages/PackageName/PackageName-1.0.4447.0/AL2_x86_64/DEV.STD.PTHREAD/build/antfiles/as-checkstyle.xml:22: The following error occurred while executing this line:
/Users/username/buildtool-pkg-cache/packages/CheckstyleAntBuildLogic/CheckstyleAntBuildLogic-1.10.311291.0/AL2_x86_64/DEV.STD.PTHREAD/build/antfiles/checkstyle.xml:92: javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Premature end of file.
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:792)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:395)
..
---------
javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Premature end of file.
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getDOM(TransformerImpl.java:603)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:782)
..
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:284)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:101)
Caused by: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Premature end of file.
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:426)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:214)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getDOM(TransformerImpl.java:581)
    ... 36 more
---------
com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Premature end of file.
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:426)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:214)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getDOM(TransformerImpl.java:581)

org.xml.sax.SAXParseException; systemId: file:/Users/username/code/workplace/Project/build/Module/Module-1.0/AL2_x86_64/DEV.STD.PTHREAD/build/buildtool-documentation/checkstyle/checkstyle_report.xml; lineNumber: 1; columnNumber: 1; Premature end of file.

向上滚动时,我可以看到真正的错误显示为良性控制台调试日志

incremental-checkstyle:
[checkstyle] Running checkstyle only on changed lines of code.
[checkstyle] Running checkstyle in incremental mode
[checkstyle] Gathering git changes.
[checkstyle] Running Checkstyle 8.7 on 2 files
[checkstyle] /Users/username/code/workplace/Project/src/Module/src/activity/com/company/org/vertical/activity/ClassName.java:129:102: expecting RPAREN, found 'emailAddr'
[checkstyle] java.lang.reflect.InvocationTargetException
     [xslt] Processing /Users/username/code/workplace/Project/build/Module/Module-1.0/AL2_x86_64/DEV.STD.PTHREAD/build/buildtool-documentation/checkstyle/checkstyle_report.xml to /Users/username/code/workplace/Project/build/Module/Module-1.0/AL2_x86_64/DEV.STD.PTHREAD/build/buildtool-documentation/checkstyle/checkstyle_report.html
     [xslt] Loading stylesheet checkstyle.xsl
     [xslt] : Error! Premature end of file.
     [xslt] : Error! com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Premature end of file.
     [xslt] Failed to process /Users/username/code/workplace/Project/build/Module/Module-1.0/AL2_x86_64/DEV.STD.PTHREAD/build/buildtool-documentation/checkstyle/checkstyle_report.xml

所以问题其实是

ClassName.java:129:102: expecting RPAREN, found 'emailAddr'

罪魁祸首行包含带有

if
运算符的
instanceof
表达式

if (newEmailAddr instanceof com.company.org.vertical.types.getAddrs.EmailAddr emailAddr) {
  ..
}

经过研究,我们发现

checkstyle
似乎不太喜欢
instanceof
运算符。

因此,我们的选择是要么将表达式的

instance
替换为
equals(..)
之类的内容,要么忽略此失败。我们决定暂时忽略这个失败。


-4
投票

另一个原因是,您应该在 mongodb 设置中将您的 IP 地址(IPv4)列入白名单。希望能解决!

© www.soinside.com 2019 - 2024. All rights reserved.