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. H5制作显示轮播图的方法Swiper

    1.需要引入Swiper插件 <!-- swiper插件 --> <link rel="stylesheet" href="https://unpkg. ...

  2. 彻底理解C++指针

    目录 目录 1 1. 概念 1 1.1. 双指针 1 1.2. 指针数组 1 1.3. 数组指针 1 1.4. 常见指针定义解读 1 2. 区别 2 3. 兼容性 2 4. 为何列数须相等? 2 5. ...

  3. SpringBoot要点之使用Actuator监控

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

  4. send 和recv小结

    不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据. 不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据. #include <sys/socket ...

  5. maven的安装、路径配置、修改库文件路径和eclipse中的配置、创建maven工程。

    注:本文来源于:杨四郎2018  <maven的安装.路径配置.修改库文件路径和eclipse中的配置.创建maven工程> 一.maven的安装 首先,先到官网去下载maven.这里是官 ...

  6. 因子分解机 FM

    特征组合 人工方式的特征工程,通常有两个问题: 特征爆炸 大量重要的特征组合都隐藏在数据中,无法被专家识别和设计 针对上述两个问题,广度模型和深度模型提供了不同的解决思路. 广度模型包括FM/FFM等 ...

  7. 洛谷P4735题解

    若想要深入学习可持久化0-1Trie树,传送门. Description: 给定数列 \(\{a_n\}\) ,支持两种操作: 在数列尾添加一个数 \(x\) ,数列长度变成 \(n+1\) ; 给定 ...

  8. 微信小程序支付接口之Django后台

    本文链接:https://blog.csdn.net/qq_41860162/article/details/89098694Python3-django-微信小程序支付接口调用工具类生成一系列微信官 ...

  9. 019 spring social

    1.原理 2. 3. 4.

  10. Springmvc 异步处理

    package com.lookcoder.haircutmember.controller.login.page.async; import org.slf4j.Logger; import org ...