web-dev-qa-db-fra.com

Pourquoi cette erreur me cause-t-elle une fin prématurée du fichier?

J'essaye d'analyser et XML response, mais j'échoue lamentablement. Je pensais au départ Que la xml n'était tout simplement pas renvoyée dans la réponse; j'ai donc élaboré le code ci-dessous avec un lien direct vers mon fichier xml en ligne. Je peux imprimer la XML à l'écran sans aucun problème. Cependant, lorsque j'appelle ma méthode d'analyse, je reçois Fin de fichier prématurée.  

Cela fonctionne si je passe l'URL directement: 

  • constructeur.parse ("");

mais échoue lorsque j'ai passé un InputStream: 

  • constructeur.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);
    }
    

Les erreurs que je reçois:

    [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)
22
Fabii

Quand tu fais ça,

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

Vous consommez tout dans instream, donc, instream est vide. Maintenant, quand essayer de le faire,

Document doc = builder.parse(instream);

L'analyse échouera car vous lui avez transmis un flux vide.

28
sbridges

Vous obtenez l'erreur parce que SAXBuilder n'est pas assez intelligent pour traiter les "états vierges". Ainsi, il recherche au moins une déclaration <xml ..> et, lorsque cela entraîne une réponse no data, il crée l'exception que vous voyez plutôt que de signaler l'état vide.

2
mist42nz

Pour ceux qui ont atteint ce post pour la réponse:

Cela se produit principalement parce que la InputStream utilisée par l'analyseur DOM est vide

Donc, dans ce que j'ai rencontré, il pourrait y avoir deux situations:

  1. La InputStream que vous avez passée dans l'analyseur a été utilisée et donc vidée.
  2. La File ou ce que vous avez créé le InputStream peut être un fichier vide, une chaîne ou autre chose. Le vide pourrait être la raison du problème. Vous devez donc vérifier votre source de la InputStream.
2
cinqS

Je suis tombé sur la même erreur et pouvais facilement trouver quel était le problème en enregistrant l'exception:

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

Ou, au lieu de consigner l'erreur, vous pouvez throw et catch où vous gérez les entrées, afin que vous puissiez imprimer l'entrée elle-même pour obtenir une meilleure indication de l'erreur.

1
Maroun