在web应用程序中不使用javascript或jquery防止多次单击提交按钮?

ngynwnxp  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(297)

我的简单web应用程序如下:我有一个jsp表单( MyForm.JSP )它接受用户输入并将其传递给我的第一个servlet( "/myfirstservlet" ).
这个servlet处理用户输入值的sql插入 Fruits 表,然后将用户重定向到我的结果servlet( "/results" ).
然后我的结果servlet检查 "ADD" 参数,如果“true”(即等于 "success" )它最终将用户重定向到我的结果jsp( Results.JSP )存储在路径中: WEB-INF/MyFolder/Results.jsp .
我的jsp表单( MyForm.JSP )也存储在路径中: WEB-INF/MyFolder/MyForm.jsp 我这样做是为了防止用户通过单击resultsjsp页面上的refresh按钮来重新提交表单,从而避免之前刚刚输入到数据库中的相同数据的多个条目。
我现在的问题是:如何防止用户在表单上多次单击提交按钮( MyForm.JSP )从而防止相同数据的多行在不使用javascript或jquery的情况下进入我的数据库?
基本上,我想在服务器而不是客户端验证表单是否只提交了一次。
我的jsp表单( MyForm.JSP ):

<form action="myfirstservlet" do="POST">
   <input type="text" name="fruit"><br>
   <input type="text" name="color"><br>
   <input type="submit" value="Submit">
</form>

我的第一个servlet( "/myfirstservlet" ):

protected void doPost(...){
   String fruit = request.getParameter("fruit");
   String color = request.getParameter("color");

   String sql = "INSERT INTO fruits (fruit, color) VALUES" + "(\"" + fruit +  "\", \""  + color +  "\");";

   utilitySQL.sqlInsert(sql); // My utility class that handles sql inserts

   response.sendRedirect("results?ADD=SUCCESS");
}

我的结果servlet( "/results" ):

protected void doPost(...){

   response.setContentType("text/html");    

   if (request.getParameter("ADD").equals("SUCCESS"))
      request.getRequestDispatcher("WEB-INF/MyFolder/Results.jsp").forward(request, response);

}

我的结果jsp( Results.JSP ):

<body>
<h1>Results JSP</h1>

  //Reads data from MySQL database and prints it as an Array List.

</body>

编辑:修复了第一个servlet中的prepared语句:

protected void doPost(...){

       String fruit = request.getParameter("fruit");
       String color = request.getParameter("color");

       try 
        {
            String sql2 = "INSERT INTO practice (fruit, color) VALUES (?, ?);";
            Connection connect = SQLHelperClass.connectOnly();
            PreparedStatement pstmt;
            pstmt = connect.prepareStatement(sql2);
            pstmt.setString(1, fruit);
            pstmt.setString(2, color);

            pstmt.execute();

            response.sendRedirect("results?ADD=success");
        } 

        catch (SQLException e) 
        {           
            e.printStackTrace();
        }

}
5sxhfpxr

5sxhfpxr1#

如果您有一个登录用户的id字段,这将更容易,因为您可以为特定用户提交的结果创建一个表,在将其输入到fruits表之前,检查该用户是否已经提交了相同的数据。
从外观上看,它看起来没有任何用户标识字段,因此防止重复的黑客方法可能是使用会话。
会话对于当前使用您的应用程序/网站的用户是唯一的。访问您的网站/应用程序的每个人都会获得自己唯一的会话id(它们存储为cookie)
例如:

protected void doPost(...){
   String fruit = request.getParameter("fruit");
   String color = request.getParameter("color");

   //unless you wanna complicate things, i would create a string out of the two parameters and store it into an arraylist of strings
   String value = fruit+color; 

   HttpSession session = (request.getSession()); //get session
   if(null == session.getAttribute("duplicates")){ //if session variable empty then we know that user has not submitted anything yet so we let them insert into db

     insertFruit(fruit,color); //add to db

     ArrayList<String> duplicates = new ArrayList<String>(); //create arraylist
     duplicates.add(value); //add our unique value
     session.setAttribute("duplicates", duplicates); //set as session variable

    }else{
     //here the session variable is not empty so that means the user has already submitted something so lets check the arraylist and make sure the value does not already exist

     ArrayList<String> duplicates = (ArrayList<String>) session.getAttribute("duplicates");

     if(!duplicates.contains(value)){
      //if arraylist does not contain the same value, then it's safe to add
       insertFruit(fruit,color); //add to db

      //forgot this part
      duplicates.add(value);
      session.setAttribute("duplicates", duplicates); //update the variable
     }

    }

   response.sendRedirect("results?ADD=SUCCESS");
}

public void insertFruit(String fruit, String color){

       try(Connection connect = SQLHelperClass.connectOnly()){
         PreparedStatement pst = connect.prepareStatement("INSERT INTO practice (fruit, color) VALUES (?, ?);");

        pst.setString(1, fruit);
        pst.setString(2, color);

        pst.executeUpdate();

          }catch (SQLException e) {
            e.printStackTrace();
          }

}

编辑1:
关于不为每个servlet重复数据库操作的注解。你需要把逻辑分开。人们通常的做法是为所有数据库操作创建一个单独的类。
例如。。。
创建一个名为 FruitDao ,这里保存所有与水果相关的数据库操作
公务舱水果刀{

public void insertFruit(String fruit, String color){

       try(Connection connect = SQLHelperClass.connectOnly()){
         PreparedStatement pst = connect.prepareStatement("INSERT INTO practice (fruit, color) VALUES (?, ?);");

        pst.setString(1, fruit);
        pst.setString(2, color);

        pst.executeUpdate();

          }catch (SQLException e) {
            e.printStackTrace();
          }

}

要从servlet调用它,只需执行以下操作:

protected void doPost(...){
   FruitDao fdao = new FruitDao(); // get the db class for fruits
   String fruit = request.getParameter("fruit");
   String color = request.getParameter("color");

   //unless you wanna complicate things, i would create a string out of the two parameters and store it into an arraylist of strings
   String value = fruit+color; 

   HttpSession session = (request.getSession()); //get session
   if(null == session.getAttribute("duplicates")){ //if session variable empty then we know that user has not submitted anything yet so we let them insert into db

     fdao.insertFruit(fruit,color); //add to db

     ArrayList<String> duplicates = new ArrayList<String>(); //create arraylist
     duplicates.add(value); //add our unique value
     session.setAttribute("duplicates", duplicates); //set as session variable

    }else{
     //here the session variable is not empty so that means the user has already submitted something so lets check the arraylist and make sure the value does not already exist

     ArrayList<String> duplicates = (ArrayList<String>) session.getAttribute("duplicates");

     if(!duplicates.contains(value)){
      //if arraylist does not contain the same value, then it's safe to add
        fdao.insertFruit(fruit,color); //add to db

      //forgot this part
      duplicates.add(value);
      session.setAttribute("duplicates", duplicates); //update the variable
     }

    }

   response.sendRedirect("results?ADD=SUCCESS");
}

相关问题