1

大家好,我正在尝试创建一个表单,允许您为某个主题创建一个实验室。它有一个下拉框,您可以在其中选择与该用户相关的主题。但是,当我加载页面时出现此错误g.apache.jasper.JasperException: java.lang.NullPointerException,对于我正在使用的当前用户,他们应该有 2 个结果

这是我的完整 servlet

import java.io.IOException;


import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class CreateLab
 */
@WebServlet("/CreateLab")
public class CreateLab extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public CreateLab() {
        super();
        // TODO Auto-generated constructor stub
    }
     int id;
     int capacity; 
     String day = ""; 
     String time = ""; 
     String room = ""; 
     int subject_id;
     int user_id;

    public void init() {
      try {
          Class.forName("com.mysql.jdbc.Driver");
          Connection con =
            DriverManager.getConnection("jdbc:mysql://localhost:3306/wae","root","");
        System.out.println("JDBC driver loaded"); 
      } 
      catch (ClassNotFoundException e) {
        System.out.println(e.toString()); 
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    } 

    /**Process the HTTP Get request*/ 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws 
  ServletException,IOException {  


    HttpSession session = request.getSession(true);

    String sql = "SELECT id,name" +
              " FROM subject " +
            " WHERE user_id="+(Integer)session.getAttribute("id");

    try{
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/wae","root","");
        System.out.println("connected");

        Statement stmt = con.createStatement();
          ResultSet res = stmt.executeQuery(sql);
          System.out.println(res);
          ArrayList<String> list1 = new ArrayList<String>();
          ArrayList<String> list2 = new ArrayList<String>();
          if (res.next()){
              do{
                   list1.add(res.getString(1));
                   list2.add(res.getString(2));
                   System.out.print(list1.add(res.getString(1)));
                   System.out.print(list2.add(res.getString(2)));

              }while(res.next());
          System.out.println("Outside");
          String[] arr1 = list1.toArray(new String[list1.size()]);
          String[] arr2 = list2.toArray(new String[list2.size()]);
          System.out.println(list1);
          request.setAttribute("res1", arr1);
          request.setAttribute("res2", arr2);
          request.setAttribute("user_id", user_id);

          }

    }catch (SQLException e) {
    } 
    catch (Exception e) {
    } 

      sendRegistrationForm(request, response, false); 
      sendPageHeader(response);
    } 

    /**Process the HTTP Post request*/ 
    public void doPost(HttpServletRequest request, 
      HttpServletResponse response) 
      throws ServletException, IOException {
      sendPageHeader(response); 
      HttpSession session = request.getSession(true);
      capacity = Integer.parseInt(request.getParameter("capacity"));

      day = request.getParameter("day"); 
      time = request.getParameter("time"); 
      room = request.getParameter("room"); 
      user_id = (int) session.getAttribute("id");
      subject_id = Integer.parseInt(request.getParameter("subject_id")); 

      System.out.print(user_id);

      boolean error = false; 
      String message = null; 
      try {
          Class.forName("com.mysql.jdbc.Driver");
          Connection con = 
            DriverManager.getConnection("jdbc:mysql://localhost:3306/wae","root","");
        System.out.println("got connection"); 
        System.out.println(id);
        Statement s = con.createStatement(); 

        String sql = "SELECT id FROM user" + 
                " WHERE id='" + user_id + "'";  
        ResultSet rs = s.executeQuery(sql); 
        if (rs.next()) {
          rs.close(); 
           sql = "INSERT INTO lab" + 
                  " (capacity, day, time, room, subject_id, user_id)" + 
                  " VALUES" + 
                  " ('" +  capacity + "'," + 
                     " '"  +  day + "'," + 
                     " '"  +  time + "'," + 
                     " '"  + room + "','" + subject_id + "','" + user_id + "')"; 

          System.out.println(sql);
          int i = s.executeUpdate(sql); 
          if (i==1) {
            message = "Successfully a new lab class."; 
            response.sendRedirect("Lecturer_labs.jsp");
          } 
        } 
          s.close(); 
          con.close(); 
        } 
        catch (SQLException e) {
          message = "Error." + e.toString(); 
          error = true; 
        } 
        catch (Exception e) {
          message = "Error." + e.toString(); 
          error = true; 
        } 
        if (message!=null) {
          PrintWriter out = response.getWriter(); 
          out.println("<B>" + message + "</B><BR>"); 
          out.println("<HR><BR>"); 
        } 
        if (error==true) 
          sendRegistrationForm(request, response, true); 
        else 
          sendRegistrationForm(request, response, false); 
        sendPageFooter(response); 
      } 

      }

这是我的jsp页面

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Mars University Lab System</title>
    <link rel="stylesheet" href="style.css" type="text/css" media="screen">
</head>

<body>
<jsp:include page="headerLecturer.jsp"/>


<tr>
<td>
</td>
</tr>

<tr>
<td>
<div id = "centrecontent">
<br>
<h3>Create Labs</h3>

<%
    String[] list1 = (String[])request.getAttribute("res1");
    String[] list2 = (String[])request.getAttribute("res2"); %>

        <form name ="createLabs" ACTION="CreateLab" method="post">
        Capacity: <input type="text" name="capacity"/><br />
        Day: <input type="text" name="day"/><br />
        Time: <input type="text" name="time"/><br />
        Room: <input type="text" name="room"/><br />
        <select name="subject_id">
        <%
        for(int i=0; i<list1.length; i++)  
        { 
        out.println("<option value="+list1[0]+"> "+list2[i]+" </option>");

        } 
        %>


        </select>
        <input type=SUBMIT value="Submit" name="Submit" />

    </form>
</div>

<jsp:include page="footer.jsp"/>


</body>

</html>
4

3 回答 3

2

该代码存在严重的安全漏洞。您正在从用户那里获取输入并将其传递给未经审查的数据库查询:

day = request.getParameter("day"); 
time = request.getParameter("time"); 
room = request.getParameter("room"); 

sql = "INSERT INTO lab" + 
              " (capacity, day, time, room, subject_id, user_id)" + 
              " VALUES" + 
              " ('" +  capacity + "'," + 
                 " '"  +  day + "'," + 
                 " '"  +  time + "'," + 
                 " '"  + room + "','" + subject_id + "','" + user_id + "')"; 
int i = s.executeUpdate(sql);

这可以通过SQL 注入攻击来利用。攻击者可能会通过将意想不到的东西传递给您的表单来损害您的数据库。

使用准备好的语句更安全(也更整洁):

sql = "INSERT INTO lab" + 
              " (capacity, day, time, room, subject_id, user_id)" + 
              " VALUES (?, ?, ?, ?, ?, ?)"; 
PreparedStatement stmt = con.prepareStatement(sql);
stmt.setInt(1,   capacity );
// set the rest.
int i = stmt.executeUpdate(sql);

为了避免你的NullPointerException,你可以在你的 try 块之前初始化list1list2然后在 catch 之后用它们 setAttribute 。这样,当尝试出现问题时,您至少会为您的表单获得一个空列表。

于 2012-10-07T08:31:14.357 回答
1

首先,在使用此属性之前,您将如何获取属性(res1 和 res2),您应该正确设置此属性...。确保在使用此属性之前,您正在使用 get 方法调用 CreateLab servlet...

我喜欢更正你程序中的一些代码......

Dont open DB connection so many time, if you are open then you must close.

列表中的重复项...

list1.add(res.getString(1));
list2.add(res.getString(2));
System.out.print(list1.add(res.getString(1)));
System.out.print(list2.add(res.getString(2)));

使用以下内容

list1.add(res.getString(1));
list2.add(res.getString(2));
System.out.print(res.getString(1));
System.out.print(res.getString(2));

使用准备好的语句来避免sql注入......

检查参数....

于 2012-10-07T10:36:54.373 回答
1

一般来说,您发布的代码有更大的改进空间,但我建议您不要像您正在做的那样处理异常:

}catch (SQLException e) {
} 
catch (Exception e) {
} 

由于未设置属性(null),它可能表明 try-catch 块中的代码出了问题。

我认为会话中的用户 ID 也可能为空。

尝试添加更详细的输出(如 println),这将为您提供有关代码数据流的更多详细信息。

那是家庭作业吗?如果那是要在生产中使用的东西 - 哎呀,它应该被完全重写。

于 2012-10-07T08:12:00.680 回答