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. Xcode 创建.a和framework静态库(转)

    最近因为项目中的聊天SDK,需要封装成静态库,所以实践了一下创建静态库的步骤,做下记录. 库介绍 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种.iOS中的静 ...

  2. LeetCode 1156. Swap For Longest Repeated Character Substring

    原题链接在这里:https://leetcode.com/problems/swap-for-longest-repeated-character-substring/ 题目: Given a str ...

  3. 干货,不小心执行了rm -f,除了跑路,如何恢复?https://www.cnblogs.com/justmine/p/10359186.html

    前言 每当我们在生产环境服务器上执行rm命令时,总是提心吊胆的,因为一不小心执行了误删,然后就要准备跑路了,毕竟人不是机器,更何况机器也有bug,呵呵. 那么如果真的删除了不该删除的文件,比如数据库. ...

  4. 关于绿盟RSAS使用时遇到的问题

    本周在使用绿盟RSAS扫描工具时遇到了一些问题: 一.扫描工具在家测试可以正常工作,到了现场设置正确但Web端页面打不开: 二.扫描器可以正常进行扫描,并且成功扫描出结果,但显示目标主机没有问题: 原 ...

  5. [Android] Android studio gradle 插件的版本号和 gradle 的版本号 的对应关系

    [Android] Android studio gradle 插件的版本号和 gradle 的版本号 的对应关系 本博客地址: wukong1688 本文原文地址:https://www.cnblo ...

  6. memset使用技巧

    memset可以对高位数组进行初始化,非常方便.需要注意的是memset的头文件是string.h和memory.h . 下面来谈memset的4个使用技巧: (注:一下dp高维数组都是全局变量,局部 ...

  7. cogs 944. [東方S3] 藤原妹红

    二次联通门 : cogs 944. [東方S3] 藤原妹红 /* cogs 944. [東方S3] 藤原妹红 最小生成树 + 树形dp 首先对原图跑最下生成树 后建出一棵树 在树上进行dp 先走到叶子 ...

  8. 第03组 Alpha事后诸葛亮

    组长博客 项目Postmortem模板 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们软件要解决的的问题是福州大学校园二手书的处理问题.应该定 ...

  9. lintcode- 22.平面表

    题目描述 22. 平面列表 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 样例 给定 [1,2,[1,2]],返回 [1,2,1,2]. 给定 [4,[ ...

  10. 使用kubectl访问kubernetes集群

    之前访问k8s都是通过token进去dashboard,如下所示.但是现在希望通过kubectl访问k8s,所以还需要进一步的配置. 1. 安装kubectl命令行工具,配置环境变量,环境变量的值指向 ...