java防重复提交_java 防止表单重复提交(serlvet)

---------FormServlet.java--------------

protected void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

/*

* 功能: 防止表单重复提交

*

* 生成一个表单的同时生成一个相应的令牌

*

* 将令牌隐藏于表单之中, 并且令牌也存入session之中

*

* 将用户提交表单到RegisterServlet时

*

* 在RegisterServlet中将表单上传的令牌与session之中的令牌对比

*

* 如果一致说明是正常提交, 在处理用户的提交后,要清空令牌, 避免用户重复提交

*

* 如果不一致说明是重复提交

*/

response.setContentType("text/html;charset=utf-8");

PrintWriter out = response.getWriter();

// 产生一个唯一的随即码 称为令牌

String token = TokenProcessor.getInstance().makeToken();

// 发送表单

out.print("

");

out.print("用户名 :
");

out.print("密码 :
");

out.print("
");

out.print("");

out.print("

");

// 将令牌存入 session 域

request.getSession().setAttribute("token", token);

}

--------RegisterServlet.java----------

protected void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

response.setContentType("text/html;charset=utf-8");

request.setCharacterEncoding("utf-8");

PrintWriter out = response.getWriter();

// 防止表单重复提交

// 获得表单提交的 token 获得 session域中保存的token

String formToken = request.getParameter("token");

String sessionToken = (String) request.getSession().getAttribute(

"token");

if (formToken == null || sessionToken == null

|| !formToken.equals(sessionToken)) {

System.out.println("表单重复提交");

// 不是正常提交

return;

}

// 获得提交的参数

String username = request.getParameter("username");

String password = request.getParameter("password");

System.out.println("username=" + username);

System.out.println("password=" + password);

// 将 session 中的令牌置为 null

request.getSession().removeAttribute("token");

// 将数据插入数据库

System.out.println("数据插入数据库.....");

// 线程休眠

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

out.write("注册成功");

}

-----------------生成令牌----------------

// 生成令牌

public String makeToken() {

// 生成 一个随机数

try {

String token = new Random().nextInt(19999999)

+ System.currentTimeMillis() + "";

// 数据指纹算法 消息摘要 md5

MessageDigest md = MessageDigest.getInstance("md5");

byte[] md5 = md.digest(token.getBytes());// 获得消息摘要

// 转为明文

// base64 算法

BASE64Encoder encoder = new BASE64Encoder();

String code = encoder.encode(md5);

return code;

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

throw new RuntimeException(e);

}

}

----------------------------------------------------------------------------------------------------------------------------------------------

Struts中的isTokenValid(request,boolean)是用来防止表单重复提交的!

Struts在你每次访问Action的时候,根据用户会话ID和当前系统时间对于每个会话生成一个唯一令牌,保存在你的Session里面,如果你在Action里的函数里面,使用了saveToken(request),那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。

如果你在你Action的方法里使用了isTokenValid,那么Struts将会从你的request里面去获取这个令牌值,然后和Session里的令牌值做比较,如果两者相等,就不是重复提交,如果不相等,就是重复提交了。

一,首先介绍一下struts提供的有关令牌环的相关方法

请求有效性处理,使用令牌可以有效的防止重复提交。

protected String generateToken(HttpServletRequest request) 创建一个令牌.

protected boolean isTokenValid(HttpServletRequest request) 检查令牌是否有效

protected boolean isTokenValid(HttpServletRequest request,Boolean reset) 检查令牌是否有效,并且重置令牌(如果reset 是true)

protected void resetToken(HttpServletRequest request) 重置令牌

protected void saveToken(HttpServletRequest request) 添加令牌

二,利用struts的同步令牌机制

利用同步令牌(Token)机制来解决Web应用中重复提交的问题,Struts也给出了一个参考实现。

基本原理:

服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,

看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给

客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次

提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

if (isTokenValid(request, true)) {

// your code here

return mapping.findForward("success");

} else {

saveToken(request);

return mapping.findForward("submitagain");

}

Struts根据用户会话ID和当前系统时间来生成一个唯一(对于每个会话)令牌的,具体实现可以参考

TokenProcessor类中的generateToken()方法。

1. //验证事务控制令牌,

会自动根据session中标识生成一个隐含input代表令牌,防止两次提交

2. 在action中:

//

// value="6aa35341f25184fd996c4c918255c3ae">

if (!isTokenValid(request))

errors.add(ActionErrors.GLOBAL_ERROR,

new ActionError("error.transaction.token"));

resetToken(request); //删除session中的令牌

3. action有这样的一个方法生成令牌

protected String generateToken(HttpServletRequest request) {

HttpSession session = request.getSession();

try {

byte id[] = session.getId().getBytes();

byte now[] =

new Long(System.currentTimeMillis()).toString().getBytes();

MessageDigest md = MessageDigest.getInstance("MD5");

md.update(id);

md.update(now);

return (toHex(md.digest()));

} catch (IllegalStateException e) {

return (null);

} catch (NoSuchAlgorithmException e) {

return (null);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工资管理系统是一个比较常见的企业管理系统,下面是一个基于Java web的工资管理系统的Servlet示例: ```java import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.sql.*; import java.util.*; public class SalaryServlet extends HttpServlet { // 处理 GET 请求 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } // 处理 POST 请求 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置编码 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 获取请求参数 String name = request.getParameter("name"); String salary = request.getParameter("salary"); // 获取数据库连接 Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary", "root", "password"); } catch (Exception e) { e.printStackTrace(); } // 插入数据 try { PreparedStatement ps = conn.prepareStatement("INSERT INTO employee(name, salary) VALUES (?, ?)"); ps.setString(1, name); ps.setString(2, salary); ps.executeUpdate(); ps.close(); } catch (Exception e) { e.printStackTrace(); } // 查询数据 List<Map<String, String>> dataList = new ArrayList<Map<String, String>>(); try { Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM employee"); while (rs.next()) { Map<String, String> dataMap = new HashMap<String, String>(); dataMap.put("name", rs.getString("name")); dataMap.put("salary", rs.getString("salary")); dataList.add(dataMap); } rs.close(); st.close(); } catch (Exception e) { e.printStackTrace(); } // 输出数据 PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>工资管理系统</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>工资管理系统</h1>"); out.println("<form method='POST'>"); out.println("姓名:<input type='text' name='name'><br>"); out.println("工资:<input type='text' name='salary'><br>"); out.println("<input type='submit' value='添加'>"); out.println("</form>"); out.println("<table border='1'>"); out.println("<tr><th>姓名</th><th>工资</th></tr>"); for (Map<String, String> dataMap : dataList) { out.println("<tr><td>" + dataMap.get("name") + "</td><td>" + dataMap.get("salary") + "</td></tr>"); } out.println("</table>"); out.println("</body>"); out.println("</html>"); // 关闭数据库连接 try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 这个Servlet实现了添加和查询员工工资的功能,其中使用了MySQL数据库进行数据存储。通过请求参数获取用户输入的姓名和工资信息,然后插入到数据库中。再查询数据库中所有的员工工资信息,并输出到页面上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值