为什么我收到此错误提前结束文件?

时间:2012-04-05 04:43:54

标签: java xml httpurlconnection

我正在尝试解析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)

7 个答案:

答案 0 :(得分:28)

当你这样做时,

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

你在instream中消耗所有东西,所以instream是空的。现在尝试这样做时,

Document doc = builder.parse(instream);

解析将失败,因为您已经传递了一个空流。

答案 1 :(得分:3)

您收到错误是因为SAXBuilder不够智能,无法处理“空白状态”。因此它至少会查找<xml ..>声明,当它导致无数据响应时,它会创建您看到的异常,而不是报告空状态。

答案 2 :(得分:2)

对于那些到达这篇文章的答案:

这主要是因为DOM解析器消耗的InputStream为空

因此,在我遇到的情况中,可能有两种情况:

  1. 您传入解析器的File已被使用并因此被清空。
  2. InputStream或您创建InputStream的任何内容可能是空文件或字符串或其他内容。空虚可能是导致问题的原因。因此,您需要检查protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } List<MyDataType> dataList = null; try { dataList = ***; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } HashMap<String, List<BigDecimal>> recordYearlyData = new HashMap<>(); String nwC = "New Customers "; String alC = "All Customers "; String lsC = "Lost Customers "; String rtC = "Rate "; List<BigDecimal> startCus = new ArrayList<>(); List<BigDecimal> newCus = new ArrayList<>(); List<BigDecimal> endCus = new ArrayList<>(); List<BigDecimal> thisYearCus = new ArrayList<>(); List<BigDecimal> lostCus = new ArrayList<>(); List<BigDecimal> rateL = new ArrayList<>(); for (MyDataType dataType : dataList) { String createDate = dataType.getOrderDate().toString(); String createDateN = createDate.substring(5, 7); Integer getDateKey = Integer.parseInt(createDateN) - 1; Integer getYear = Integer.parseInt(createDate.substring(0,4)); BigDecimal tenant_id = dataType.getTenantID(); createDateLabel = monthNames[getDateKey]; if (getYear != yearChecker) { String yearLabel = String.valueOf(getYear - 1); for (BigDecimal tenant : thisYearCus) { if (newCus.contains(tenant) || startCus.contains(tenant)) { endCus.add(tenant); } } for (BigDecimal tenant : startCus) { if (!thisYearCus.contains(tenant)) { lostCus.add(tenant); } } double rate = 1.0; if (startCus.size() == 0) { rate=1.0; } else if (startCus.size() > 0){ rate = ((double) endCus.size() - (double) newCus.size())/(double) startCus.size(); } rateL.add(BigDecimal.valueOf(rate)); recordYearlyData.put(alC+yearLabel, thisYearCus); recordYearlyData.put(nwC+yearLabel, newCus); recordYearlyData.put(lsC+yearLabel, lostCus); recordYearlyData.put(rtC+yearLabel, rateL); rateL.clear(); startCus.clear(); startCus.addAll(thisYearCus); thisYearCus.clear(); endCus.clear(); newCus.clear(); lostCus.clear(); yearChecker = getYear; } if (!thisYearCus.contains(tenant_id)) { thisYearCus.add(tenant_id); } if (!startCus.contains(tenant_id)) { if(!newCus.contains(tenant_id)) { newCus.add(tenant_id); } } } request.setAttribute("newCusTable", recordYearlyData.get("New Customers 2015")); request.setAttribute("allCusTable", recordYearlyData.get("All Customers 2015")); request.setAttribute("lostCusTable", recordYearlyData.get("Lost Customers 2015")); request.setAttribute("retRate", recordYearlyData.get("Rate 2015")); RequestDispatcher view = request.getRequestDispatcher("/Sales.jsp"); view.forward(request, response); }
  3. 的来源

答案 3 :(得分: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处理条目的位置,因此您可以打印条目本身以更好地指示错误。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我通过将源Feed从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);

答案 6 :(得分:0)

一次使用inputstream,不要多次使用它,并且 做inputstream.close()