JAVA–利用Filter和session防止页面重复提交
解决思路:
1 用户访问表单页面,先经过过滤器,过滤器设置一个随机id作为token令牌, 并将该token放入表单隐藏域中.
2 表单响应到浏览器,用户填充数据后提交请求;
3 请求经过过滤器,过滤器获取表单中的令牌进行验证,如果和之前生成的令牌一致,则将请求放行,并且清空令牌;
4 如果用户重复提交表单,请求经过过滤器,过滤器进行验证.因为第一次放行后令牌已经清空失效,令牌不一致,不放行.跳转到提醒界面.

需用知识:
1 过滤器基础知识
2 servlet基础知识
3 filter基础知识
4 jsp基础知识

代码实现

1 jsp实现form表单页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="post">
<!-- 利用表单的隐藏域 保存token令牌 -->
<!-- ${token}等价于req.getsession().getAttribute("token")--> <input type="hidden" name="token" value="${token}" />
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="login"/>
</form>
</body>
</html>

  

2 filter过滤器

package com.woniu.filter.controler;

import java.io.IOException;
import java.util.UUID; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet Filter implementation class TokenFilte
*/ //过滤所有servlet
@WebFilter("*") public class TokenFilte implements Filter { public TokenFilte() {
// TODO Auto-generated constructor stub
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
//设置编码集
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charser=utr-8");
//向下转型
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response; //获取表单的token
String parameterToken = req.getParameter("token");
//获取session中的token
String sessionToken = (String) req.getSession().getAttribute("token"); //判断表单的token,不为空说明用户已经提交form表单,需要验证是否重复提交,
//为空说明是第一次进入登录页面,需要设置token
if (parameterToken!=null) {
//判断两个令牌是否相等,相等则放行,并重置令牌
if(parameterToken.equals(sessionToken)) {
//重置令牌
req.getSession().removeAttribute("token");
chain.doFilter(request, response);
}else {//说明是重复提交,转发到提示页面
req.getRequestDispatcher("repeatReminder").forward(request, response); }
}else {//第一次进来,需要设置令牌
//生成宇宙唯一码
String token = UUID.randomUUID().toString();
//设置session
req.getSession().setAttribute("token",token);
//放行
chain.doFilter(request, response);
} } @Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub } }

  

3 表单响应的servlet
利用线程睡30秒,模拟网络拥堵

package com.woniu.filter.controler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class PrintUser
*/
@WebServlet("/login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L; public Login() {
super();
// TODO Auto-generated constructor stub
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//线程睡30秒,便于演示网络拥堵
Thread.sleep(30000);
response.getWriter().write("登录成功");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }

  

4 重复提交时响应的servlet
重复提交时跳转到该提醒页面

package com.woniu.filter.controler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class repeatReminder
*/
@WebServlet("/repeatReminder")
public class repeatReminder extends HttpServlet {
private static final long serialVersionUID = 1L;
public repeatReminder() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("页面正在处理,请勿重复提交");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
} }

  

JAVA–利用Filter和session防止页面重复提交的更多相关文章

  1. PHP避免刷新页面重复提交

    PHP避免刷新页面重复提交 2013-07-09 15:27 匿名 | 浏览 3567 次 编程语言 情景:从html提交数据到x.php 在x.php中$_POST数据写库并且显示,当x.php刷新 ...

  2. ASP.NET防止连续多次点击提交按钮 导致页面重复提交

    PS:实际使用中发现,第①种方法在火狐浏览中有时候有问题.第2种方法,在各个浏览器中都没问题 近做项目遇到了这样的情况: 公司网络比平常慢了不少,在点击保存按钮提交页面后需等待挺长的一段时间,忍不住手 ...

  3. java struts2入门学习--防止表单重复提交.OGNL语言学习

    一.知识点回顾 防止表单重复提交核心思想: 客户端和服务器端和写一个token,比较两个token的值相同,则非重复提交;不同,则是重复提交. 1.getSession三种方式比较: request. ...

  4. php止刷新页面重复提交

    利用session来解决,首先新建一个session,并赋值,第一次提交后改变session的值,当第二次再此提交此内容时,如果不是我们的赋值,就不在处理传过来的数据.如:<?php sessi ...

  5. session实现防止重复提交,以及验证

    参考文档 1.生成Token的参考文档.http://www.cnblogs.com/TianFang/p/3180899.html 2.主要参考文档.http://www.cnblogs.com/x ...

  6. c#.net防止按F5刷新页面重复提交的方法

    在网上购物的过程中,提交完一个页面后,如果此时按f5刷新,则会弹出一个提示:如果继续,则会重新发送提交我们刚才提交的内容,这个问题应该规避掉,不然总是重复提交付款,那可不是件好事. 在c#.net中的 ...

  7. java后端使用token处理表单重复提交

    保证接口幂等性,表单重复提交 前台解决方案:提交后按钮禁用.置灰.页面出现遮罩后台解决方案:   使用token,每个token只能使用一次1.在调用接口之前生成对应的Token,存放至redis 2 ...

  8. Token机制,防止web页面重复提交

    1.业务要求:页面的数据只能被点击提交一次 2.发生原因: 由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交 3.解决办法: 集群环境:采用token加redis(redis单线 ...

  9. UseSubmitBehavior="false" 防止页面重复提交bug

    OnClientClick="this.disabled=true;" UseSubmitBehavior="false" 注: 1.当设置UseSubmitB ...

随机推荐

  1. JS中的let变量和var变量的区别

    let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]; let允许你声明一个作用域被限制在块级中的变量.语句或者表达式.在F ...

  2. SpringBoot要点之使用Actuator监控

    Actuator是Springboot提供的用来对应用系统进行自省和监控的功能模块,借助于Actuator开发者可以很方便地对应用系统某些监控指标进行查看.统计等. 在pom文件中加入spring-b ...

  3. CCF 201909-5 城市规划

    试题编号: 201909-5 试题名称: 城市规划 时间限制: 3.0s 内存限制: 512.0MB 问题描述: 几乎是Gym102222G的原版,详解见上一篇博文 /* 贡献+树形dp+01背包 * ...

  4. 一起学Makefile(一)

    make和makefile makefile文件帮助我们记录了整个项目工程的所有需要编译的文件列表,这样我们在编译时仅需要输入简单的make命令就能编译出我们期望的结果. makefile文件反映了整 ...

  5. 【AtCoder】 ARC 100

    link C-Linear Approximation 给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\) 把 ...

  6. 帝国cms伪静态设置方法

    众所周知,动态页面不利于收录和排名.伪静态可以完美的解决这问题,配合百度云加速CDN,可以让动态页面有静态页面一样快的访问速度. 今天开拓族给大家带来帝国CMS伪静态的详细设置方法. 1.栏目设置为动 ...

  7. asp.net core 使用 Serilog

    安装NuGet包 PM> Install-Package SerilogPM> Install-Package Serilog.AspNetCorePM> Install-Packa ...

  8. WINDOWS 命令行调用SAS代码 并指定输出路径 示例

    ECHO "设置SAS.EXE 路径" SET PATH=D:\Program Files\SASHome\SASFoundation\9.4\SAS.EXE echo " ...

  9. centos7没有ifconfig命令解决办法

    输入ifconfig 提示不存在   首先确认下是否是环境变量没有ifconfig 引起. ls /sbin/ifconfig   以上确定了系统是没有安装ifconfig,下面我们来安装 yum i ...

  10. mysql 日期自动自动添加及更新为当前时间

    1. 虽然mysql中日期时间类型比较多,但是支持默认值的类型只有timestamp,详见这里. 2. 希望新增记录时自动写入当前时间,建表语句如下: `create_time` timestamp ...