【问题标题】:Servlets: issue with storing/printing specific attributes using HttpSession, arrayServlet:使用 HttpSession、数组存储/打印特定属性的问题
【发布时间】:2015-11-12 14:59:15
【问题描述】:

我还是 servlet 和 JDBC 方面的新手,希望对以下代码有所帮助:

try{
        String selectSQL = "select * from product_list where category = '"+category+"'";
        Statement stmt = conn.createStatement();
        ResultSet rs1 = stmt.executeQuery(selectSQL);

        ArrayList<Float> idList = new ArrayList<Float>();

out.println("<table border=\"1\"><tr><th>Item_ID</th><th>Item_name</th><th>Title</th><th>Category</th><th>Image_name</th><th>Price</th><th>Stock_Count</th></tr>");

while(rs1.next()){

    out.println("<tr><td>"+ rs1.getFloat("item_id") + "</td>");
    out.println("<td>" + rs1.getString("item_name") + "</td>"); 
    out.println("<td>"+"<a href =\"ItemDetail\">" + rs1.getString("title")+"</a>" + "</td>");
    out.println("<td>" + rs1.getString("category") + "</td>");
    out.println("<td>" + rs1.getString("image_name") + "</td>");
    out.println("<td> " + rs1.getFloat("price") + "</td>");
    out.println("<td> " + rs1.getFloat("stock_count") + "</td>");
    out.println("</tr>");
         HttpSession session = request.getSession(true);
        idList.add(rs1.getFloat("recording_id"));
        session.setAttribute("id", idList);
}
out.println("</table>");

        conn.close();
    } catch(SQLException se) {
        System.err.println(se);
    }

我想要做的是它将每个 item_id 存储在会话中,但只显示另一个 servlet 中用户单击其标题链接的详细信息(每个标题都有相同的超链接),我有试图将所有 id 存储在一个数组列表中,但在另一个接收数组列表的 servlet 上没有显示任何内容,我在那里做错了什么,任何帮助将不胜感激。

这是在不同的 servlet 中用于从上表接收属性的代码

HttpSession session = request.getSession(true);
    ArrayList<Float> id = (ArrayList<Float>) session.getAttribute("id");

【问题讨论】:

  • 代码已更新
  • 那是一些非常讨厌的代码,但请尝试将 HttpSession 放在您打印的表格之前。在打印输出之前创建一个会话
  • 我知道 -_- 代码很糟糕,在我打印表格之前放置 HttpSession 并没有什么不同,其他 servlet 中仍然没有显示任何内容,我认为有问题数组部分的代码。

标签: java arrays servlets jdbc httpsession


【解决方案1】:

这是一个工作示例代码。相应修改

 //My first servlet using Java-8
 try (Connection con = DriverManager.getConnection("xxxx")) {
        String category = "fish";
        try (PrintWriter out = response.getWriter()) {
            try (ResultSet rs1 = con.createStatement()
                    .executeQuery("select * from product_list where category = '" + category + "'")) {
                HttpSession session = request.getSession();
                ArrayList<Float> list = new ArrayList<>();
                out.print(
                        "<table border=\"1\"><tr><th>Item_ID</th><th>Item_name</th><th>Title</th><th>Category</th><th>Image_name</th><th>Price</th><th>Stock_Count</th></tr>");
                while (rs1.next()) {
                    list.add(rs1.getFloat("item_id"));
                    out.println("<tr><td>" + rs1.getFloat("item_id") + "</td>");
                    out.println("<td>" + rs1.getString("item_name") + "</td>");
                    out.println("<td>" + "<a href ='" + request.getContextPath() + "/Second?id="+rs1.getFloat("item_id")+"'>"
                            + rs1.getString("title") + "</a>" + "</td>");
                    out.println("<td>" + rs1.getString("category") + "</td>");
                    out.println("<td>" + rs1.getString("image_name") + "</td>");
                    out.println("<td> " + rs1.getFloat("price") + "</td>");
                    out.println("<td> " + rs1.getFloat("stock_count") + "</td>");
                    out.println("</tr>");
                }
                session.setAttribute("list", list);
                out.println("</table>");
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

我的第二个 servlet 在这里

 protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    // then just use that to get it through a GET Http Method
    String id = request.getParameter("id");
    HttpSession session = request.getSession();
    ArrayList<Float> list = (ArrayList<Float>) session.getAttribute("list");
    response.getWriter().append("item:  ").append(String.valueOf(list.get(0)));
}

在屏幕上打印输出 item: 45.0

希望对你有帮助。

【讨论】:

  • 谢谢,上面的代码可以正常工作,但是我如何将它应用到我自己的代码中呢?对不起,我仍然是编码的菜鸟。
  • 见编辑。但是根据我没有修改数据库连接字符串进行修改
  • 推荐你使用数据源池,幸运的是你的tomcat提供了一个
  • 代码正在运行,但不幸的是它没有做我想要它做的事情,目前它正在从 (0) 开始打印第二个 servlet 中的 item_id 但我想要它做的是仅从用户单击同一行上的标题链接的那个中获取 item_id,例如 item_id '1' 的标题为“Apple”,并且用户单击“Apple”链接,然后它将详细显示根据 Apple 的 item_id 的项目。我知道这很乱......
  • 它仍然只在 (0) 处显示 item_id,这不是我点击标题的那个
【解决方案2】:

杰夫,杰夫,杰夫……

我认为你的问题的答案很简单,但我想帮你清理一下,因为这里有很多事情可以做得更好。这段代码有资源泄露,可以教你一些坏习惯。

ID 没有正确显示的原因可能是这一行:

    HttpSession session = request.getSession(true);
    idList.add(rs1.getFloat("recording_id"));
    session.setAttribute("id", idList);
} //End while

每次遍历 ResultSet 时,都会重置 idList 属性。需要在循环外获取会话,修改ArrayList,然后设置一次属性。

HttpSession session = request.getSession(true); //Get the session only once
ArrayList<Float> idList = new ArrayList<Float>();   //Declare output variables outside of the try block.

//Now declare your JDBC resources; always declare them as null outside of the try block.
//This allows you to close them properly later.

PreparedStatement stmt = null;
ResultSet rs1 = null;

try{
    String selectSQL = "select * from product_list where category = ?";

    stmt = conn.prepareStatement(selectSQL);

    stmt.setString(1, category);

    rs1 = stmt.executeQuery(selectSQL);

    out.println("<table border=\"1\"><tr><th>Item_ID</th><th>Item_name</th><th>Title</th><th>Category</th><th>Image_name</th><th>Price</th><th>Stock_Count</th></tr>");

    while(rs1.next()){

         out.println("<tr><td>"+ rs1.getFloat("item_id") + "</td>");
         out.println("<td>" + rs1.getString("item_name") + "</td>"); 
         out.println("<td>"+"<a href =\"ItemDetail\">" + rs1.getString("title")+"</a>" + "</td>");
         out.println("<td>" + rs1.getString("category") + "</td>");
         out.println("<td>" + rs1.getString("image_name") + "</td>");
         out.println("<td> " + rs1.getFloat("price") + "</td>");
         out.println("<td> " + rs1.getFloat("stock_count") + "</td>");
         out.println("</tr>");
         idList.add(rs1.getFloat("recording_id")); //Add to the list in the loop.

       }

    out.println("</table>");

    } catch(SQLException se) {
        System.err.println(se); //This is OK, but consider 'throw new RuntimeException(se)' here instead so that the exception propagates.
    } finally {
   //Close the resources backwards from the way that they were opened.
   //Check them all for null first in case there's an error in the middle somewhere, 
   //otherwise you'll get a NullPointerException from the finally block and it will "swallow"
   //the original error.
   if(rs1 != null) {
      try {
        rs1.close();
      } catch(SQLException x) {
        System.err.println(x); //Don't throw here; keep trying to close resources
      }
   }

   if(stmt != null) {
      try {
        stmt.close();
      } catch(SQLException x) {
        System.err.println(x); 
      }
   }

   if(conn != null) {
      try {
        stmt.close();
      } catch(SQLException x) {
        System.err.println(x);
      }
   }
}

session.setAttribute("id", idList); //Set the list once and only once.

【讨论】:

  • 感谢您的回复,我尝试运行上面的代码却报错'java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).'显示在控制台上,是什么意思?
  • 另外,这段代码有什么作用? stmt.setString(1,category);
  • 上面的代码使用了PreparedStatement,它将一个变量绑定到“category”的值。这可以防止 SQL 注入攻击,因为参数值不是语句的一部分。如果您要改用 Statement,则有人可以将 ; DROP TABLE PRODUCT_LIST 作为类别并让您的表格消失。至于错误...您确定 selectSQL 包含?,对吗?这是关键。
  • 我当前的selectSQL是这样的 String selectSQL = "select * from product_list where category = '"+category+"'";我需要放吗?那里的某处或@Brad
  • 而不是select * from product_list where category = '"+category+"' 使用select * from product_list where category = ? 问号替换串联的“类别”。
猜你喜欢
  • 2011-06-23
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多