2009-05-10 7 views
0

Mon problème est que je dois définir une variable dans une instruction try sinon j'obtiens une erreur de compilation.Comment éviter de définir une variable dans une instruction try

Plus tard, j'ai besoin d'utiliser cette variable, mais il est maintenant hors de la portée, ou du moins je crois. J'initialise la variable en dehors de l'instruction try et la mets à zéro, je pensais qu'elle pourrait alors être accessible à l'extérieur, mais je reçois quand même un NullPointerException.

Le code est ci-dessous, avec beaucoup de sorties pour faciliter la lecture - Je sais que c'est un mauvais code, mais je suis nouveau avec Servlets et je voulais juste le voir fonctionner avec toutes les parties mobiles .

J'ai créé une autre classe qui appelle createDocs (...) et transmet les paramètres requis, et cela fonctionne correctement. Donc, cela me rend curieux de savoir pourquoi quand j'appelle rs.getString("name"), je reçois le NullPointerException, car c'est exactement ce que je fais de l'autre classe (exécution d'une méthode principale pour plus de commodité) et cela fonctionne comme prévu.

La variable en question est la variable ResultSet "rs" -

public class AgReportServlet extends HttpServlet { 

    private static final long serialVersionUID = 1L; 

    public AgReportServlet() { 
     super(); 
    } 

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     ResultSet rs = null; 
     try { 
      rs = docs.getDocs(con, start, end, zone, locality); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     response.setContentType("text/xml"); 
     PrintWriter out = response.getWriter(); 
     out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" + 
       out.println(
         "<table border=\"0\" cellspacing=\"0\" cellpadding=\"6\">\n"); 

     // I have a resultset object need to iterate through it to display the file names 

     try { 
      while (rs.next()) { // page through the result set 

       out.println(
         " <tr>\n" + 
           " <td>: " + rs.getString("name") + "</td>\n" + 
           " </tr>\n" 
       ); 
      } 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     out.println(
       "</table></body>\n" + 
         "</html>" 
     ); 

     out.flush(); 
     out.close(); 
    } 
} 
+0

Vous vous rendez compte que le code semble avoir une vulnérabilité XSS stockée? –

+0

Je pense que le vrai problème est qu'après une exception est levée, vous continuez comme si rien ne se passait.Si vous lancez une exception ou renvoyez une erreur, vous n'aurez pas à définir rs. Note: Où va la trace de la pile, l'utilisateur ne la verra pas. Il peut être plus convivial de laisser l'utilisateur savoir qu'une erreur s'est produite. –

Répondre

5

Votre problème est que si cette déclaration:

rs = docs.getDocs(con, start, end, zone, locality); 

jette une exception alors la valeur de rs est encore null. Donc ce que je ferais, c'est déplacer la boucle dans le même bloc try-catch. Alternativement, vous pouvez vérifier s'il est encore nul avant d'essayer de l'utiliser.

La définition de la valeur null en dehors du bloc try-catch n'est cependant pas un mauvais code. C'est exactement ce que vous devez faire si vous voulez que la variable rs soit en dehors du bloc try (et cela inclut dans l'une des clauses catch). Votre boucle while rs devrait probablement être dans le même bloc try.

+0

Merci cletus, mais savez-vous pourquoi je reçois une exception NullPointerException lors de l'appel rs.getString ("nom")? – Ankur

+0

J'ai manqué un point clé de votre argument. Maintenant mis à jour. Si vous vérifiez vos journaux de servlet, vous verrez sans doute qu'une exception a été levée, d'où la valeur nulle. – cletus

2

Pourquoi ne pas ajouter vous simplement

if(rs != null) 

avant

while(rs.next()) 

Cela devrait aider (pour autant que je le comprends)

+0

Merci, je vais le faire. Mais dans ce cas, rs ne devrait pas être nul. Les données existent et lorsque la méthode est appelée à partir d'une autre classe, cela fonctionne correctement. Est-ce le fait qu'il est null lié à la rs = docs.getDocs (con, start, end, zone, localité); passe dans une déclaration d'essai? – Ankur

+0

Oui, comme d'autres l'ont déjà dit avant, vous ne pouvez pas être sûr que rs n'est pas nul après le try-block car il peut y avoir une erreur. –

4

La façon dont vous déclarez la variable rs et le premier bloc try/catch est correct.

C'est juste que, après le premier essai/catch, vous devez vous rappeler que sera toujours être nul s'il y avait une erreur dans le premier essai/catch. Donc, assurez-vous de tester rs pour null avant d'essayer d'y accéder.

0

Merci à tous pour votre aide. D'abord vous m'avez aidé à identifier qu'il devait y avoir une sorte d'exception. Quand j'ai regardé la console Tomcat je pouvais voir que c'était une erreur de classe et non de fonds pour le connecteur MySQL. J'avais inclus cela dans mon projet, mais pas dans le projet lui-même - je l'ai paresseusement référé dans mon répertoire lib, donc finalement l'exception a causé le problème, mais en utilisant vos suggestions comme if (rs! = Null) m'a aidé à la cause première. Au début, je pensais que cela avait quelque chose à voir avec la variable étant hors de la portée. Clairement, ce n'était pas ça.

Questions connexes