为了账号安全,请及时绑定邮箱和手机立即绑定

防止在 Web 应用程序中不使用 JavaScript 或 JQuery 的多次提交按钮单击?

防止在 Web 应用程序中不使用 JavaScript 或 JQuery 的多次提交按钮单击?

繁星coding 2021-11-24 14:52:52
我的简单 web 应用程序如下: 我有一个 JSP 表单 ( MyForm.JSP),它接受用户输入并将其传递给我的第一个 servlet ( "/myfirstservlet")。这个 servlet 处理用户输入值的 SQL 插入到我的Fruits表中,然后将用户重定向到我的结果 servlet ( "/results")。我的结果 servlet 然后检查 an"ADD"参数,如果“真”(即等于"success"),它最终将用户重定向到我的结果 JSP(Results.JSP),它存储在路径中: WEB-INF/MyFolder/Results.jsp。我的 JSP 表单 ( MyForm.JSP) 也存储在路径中: WEB-INF/MyFolder/MyForm.jsp我这样做是为了防止用户通过单击 Results JSP 页面上的刷新按钮重新提交表单,从而避免对之前刚刚输入到数据库中的相同数据进行多次输入。我现在的问题是:如何防止点击提交按钮,用户多的窗体上的时间(MyForm.JSP),从而防止相同数据的多个行越来越进入我的数据库WITHOUT使用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>
查看完整描述

1 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

如果你有一个登录用户的 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,在这里保存所有与水果相关的数据库操作


公共类 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");

}


查看完整回答
反对 回复 2021-11-24
  • 1 回答
  • 0 关注
  • 113 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信