spring MVC 后台token防重复提交

springMVC中基于token防止表单重复提交方法 本篇文章主要介绍了springMVC中基于token防止表单重复提交方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 立即下载

spring MVC 后台token防重复提交解决方案

思路

1.添加拦截器,拦截需要防重复提交的请求
2.通过注解@Token来添加token/移除token    
3.前端页面表单添加
    <input name='token' type='hiden'>

(如果是Ajax请求则需要在请求的json数据中添加token值)

核心源码

拦截器源码实现

/**
 * com.hshc.as.web.interceptor.TokenInterceptor.java
 * Copyright 2018 Lifangyu, Inc. All rights reserved.
 * HUASHENGHAOCHE PROPRIETARY/CONFIDENTIAL.Use is subject to license terms.
 */
package com.hshc.common.interceptor;

import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Random;
import java.util.UUID;

/**
 * Desc:防重复提交的拦截器
 * <p>
 * Created by lifangyu on 2018/02/27.
 */
public class TokenInterceptor extends HandlerInterceptorAdapter {

    Logger logger = Logger.getLogger(TokenInterceptor.class);

    static String splitFlag = "_";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Token annotation = method.getAnnotation(Token.class);
            if (annotation != null) {
                boolean needSaveSession = annotation.add();
                if (needSaveSession) {
                    Random random = new Random();
                    String uuid = UUID.randomUUID().toString().replace(splitFlag, String.valueOf(random.nextInt(100000)));
                    String tokenValue = String.valueOf(System.currentTimeMillis());
                    request.setAttribute("token", uuid + splitFlag + tokenValue);
                    // session 中 token 的key 每次都是变化的[适应浏览器 打开多个带有token的页面不会有覆盖session的key]
                    request.getSession(true).setAttribute(uuid, tokenValue);
                }
                boolean needRemoveSession = annotation.remove();
                if (needRemoveSession) {
                    if (isRepeatSubmit(request)) {
                        logger.warn("please don't repeat submit,url:" + request.getServletPath());
                        return false;
                    }
                    String clinetToken = request.getParameter("token");
                    if (clinetToken != null && clinetToken.indexOf(splitFlag) > -1) {
                        request.getSession(true).removeAttribute(clinetToken.split("_")[0]);
                    }
                }
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 判断是否是重复提交
     *
     * @param request
     * @return
     */
    private boolean isRepeatSubmit(HttpServletRequest request) {

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

        if (clinetToken == null) {
            return true;
        }
        if (clinetToken.indexOf(splitFlag) > -1) {
            String uuid = clinetToken.split("_")[0];
            String token = clinetToken.split("_")[1];
            String serverToken = (String) request.getSession(true).getAttribute(uuid);
            if (serverToken == null) {
                return true;
            }
            if (!serverToken.equals(token)) {
                return true;
            }
        }

        return false;
    }
}

注解源码

/**
 * com.hshc.as.web.interceptor.Token.java
 * Copyright 2018 Lifangyu, Inc. All rights reserved.
 * HUASHENGHAOCHE PROPRIETARY/CONFIDENTIAL.Use is subject to license terms.
 */
package com.hshc.common.interceptor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Desc:Token 注解
 * <p>
 * Created by lifangyu on 2018/02/27.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {

    /**
     * 添加token的开关[true:添加;false:不添加,default:false]
     *
     * @return
     */
    boolean add() default false;

    /**
     * 移除token的开关[true:删除;false:不删除,default:false]
     *
     * @return
     */
    boolean remove() default false;

}

拦截器的配置

在springMVC的servlet配置文件中配置拦截器

    <!-- 拦截器配置 -->
    <mvc:interceptors>
        <!-- 配置Token拦截器,防止用户重复提交数据 -->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.hshc.as.web.interceptor.TokenInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

使用指南

1.在进入页面的controller方法上添加注解@Token(add=true)
    @Token(add = true)
    @RequestMapping("toPickups***ByVIN")
    public String toPickups***ByVIN(Model mv) {
        ......
        return "fee/carPickup****";
    }
2.在页面carPickupEdit.html添加
<form id="payment_submit_form" class="form-horizontal" action="${ctx}/fee/pay/addOrModifyFee****.do" method="post">
        ......
        <input type="hidden"  name="token" value="${token}"/>
        <!-- 注:name必须是token -->
        ......
</form>

3.在防止重复提交的controller方法上添加@Token(remove = true)

java
@Token(remove = true)
@RequestMapping("addOr****Fee***")
public String addOr****FeePayment() throws Exception {
......
return "redirect:toCarFee***.htm?listView=carFeePaymen***&jsView=carFee***List";
}

BUCK电路为何无法实现100%占空比?自举电路原理与替代方案解析 在开关电源设计中,DC-DC转换器是实现电压变换的核心器件,其工作原理基于功率开关管的周期性导通与关断。BUCK(降压)电路作为一种经典拓扑,通过调节开关管的占空比来控制输出电压。然而,其占空比存在理论上限,无法达到100%,这一限制源于高边开关管的驱动需求。为了驱动高边N沟道MOSFET(NMOS),需要栅极电压高于源极电压,而自举(Bootstrap)电路通过利用开关节点电压的跳变,巧妙地生成了这一高压驱动信号。自举电路必须在每个开关周期内存在续流阶段(低边管导通)为电容充电,这从根本上限制了最大占空比 阅读详情

相关推荐

别再乱按F8了!Win10系统修复的正确姿势:用管理员CMD运行sfc /scannow

本文详细介绍了Windows 10系统修复的正确方法,重点推荐使用管理员CMD运行`sfc /scannow`命令。相比传统的F8键和重装系统,这一方法更高效且安全,能解决大多数系统文件损坏问题。文章还提供了管理员CMD的启动方式、sfc命令的完整参数解析以及实战故障排除流程图,帮助用户快速恢复系统健康。

weixin_29218963的博客 459

JavaWeb学习总结(十三)——使用Session防止表单重复提交

  在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复提交的常见应用场景 有如下的form.jsp页面 1 &lt;%@ page language="java" import="java.util.*" pageEncoding="UTF...

weixin_33939380的博客 816

STM32F407+LAN8720A+LwIP实战:FreeModbus TCP从机功能开发指南

本文详细介绍了基于STM32F407和LAN8720A硬件平台,结合LwIP协议栈实现FreeModbus TCP从机功能的开发指南。内容涵盖硬件连接、LwIP移植、FreeModbus TCP从机实现、任务调度及调试技巧,为工业控制领域的以太网通信开发提供实用参考。

weixin_29190651的博客 546

Spring Cloud ZuulFilter 简单实现防重复提交

重复提交定义: 用户在一次请求未完成期间,不可重复请求,即用户一次请求服务器未完成响应时,不可再次发起同样的请求 实现方案: 请求开始时 将用户的id+请求地址+请求参数 作为key 缓存在redis中,请求完成后移除redis缓存的key 实现代码: package com.yd.zuul.filter; import com.alibaba.fastjson.JSON; impo...

weixin_40715236的博客 4742

72-dify案例分享-揭秘!如何用 Dify 实现多语言 PDF 文档原格式翻译

本文围绕 Dify 1.6 + 版本,演示搭建 PDF 文档翻译 Agent:配置 MCP 服务、构建 Agent 并以 URL 传文件测试,实现高效翻译,展现 MCP 跨工具复用与简化集成的优势,助力 AI 应用开发。

个人技术 2286

储能逆变器动态无功补偿:从原理到算法实现

本文深入解析了储能逆变器动态无功补偿的核心原理与算法实现。通过四象限运行与解耦控制技术,储能逆变器可在充放电的同时,快速、精准地调节无功功率,有效提升电网电能质量与功率因数。文章详细阐述了从相位调节、容量限制到PI控制算法的完整技术路径,并结合工程实践,探讨了其在光伏/储能系统中的协同控制策略与进阶应用价值。

weixin_29216353的博客 207

spring cloud zuul 之并发情况限流处理

1、简介说明 高并发的情况肯定是实际场景中经常碰到的情况,比如说我们经常遇到到订单,用户下单等操作。 那么这种情况下限流措施肯定是必须的,本文我们就来看看springcloud-zuul中是怎么处理限流操作的。 2、创建项目 2.1 简单的项目结构: 父工程: toto 注册中心服务:erueka 网关服务:gateway 订单服务服务:order 用户服务:user 3、准备需要用到的依赖 网关服务中我们需要引入的pom依赖 这里其他服务中依赖就不一一展示了。不想自己搭建项目的就关注公众号"小码农码

小码农吗 3015

AT89C52单片机+LCD屏:手把手教你做一个能算小数和负数的计算器(附完整代码)

本文详细介绍了如何使用AT89C52单片机和LCD1602显示屏构建一个支持小数和负数运算的高精度计算器。从硬件选型、系统架构设计到核心算法实现,提供了完整的代码示例和优化技巧,特别适合51单片机初学者和课程设计参考。

weixin_30374009的博客 370

spring boot——请求与参数校验——@RequestMapping注解——补充

https://www.cnblogs.com/xiaobaibailongma/p/16974031.html package org.example.controller.requestparam; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.Re...

小白龙白龙马的博客 265

Python爬虫实战:全面采集国家自然科学基金项目数据的全流程指南

国家自然科学基金委员会(NSFC)支持基础研究、应用基础研究,是我国科研投入的核心项目之一。公开的项目数据包括项目名称、负责人、资助金额、年度、单位等,具备极高科研和数据分析价值。requests:基础HTTP请求库,简单直观:异步HTTP请求库,适合大规模并发:HTML解析,提取数据:处理JavaScript渲染网页pandas:数据分析与清洗:数据库存储:重试机制实现。

2201_76125261的博客 753

【AI智能体】Claude Code +Superpowers 项目实战操作详解

Claude Code +Superpowers 项目实战操作详解

congge 4048

项目中使token

项目中使token 如果项目架构采用前后端分离,并采用分布式架构,通过定义接口API,与前端进行数据交互,前端通过html前行实现。若加入移动端(Andriod,ios)实现,可直接使用API接口实现即可。由于该项目进行前后端分离,session就没有意义了。并且移动端也是无法使用session的。那么需要使用token进行session管理,通过搭建一个认证系统负责用户身份验证,并...

weixin_30326745的博客 375

全网最强AI辅助课题申报教程!超详细流程拆解,助你快速提高课题申报成功率(附各部分高效提示词)

实验法要详细说明自变量、因变量、实验类型、实验过程、实验步骤、测量工具名称、被试取样方式、无关变量控制方法。这个部分就是让评审专家相信我们有能力把这个项目干成,写的时候要重点突出两块内容:第一是研究基础,包括你或团队在相关领域已有的研究成果,比如发表的论文、承担过的课题、获得过的奖励、相关研究经验等,要具体、有说服力;课题申报专门给我们留了一小节用来突出课题的创新之处,不管是研究角度、研究对象、研究方法,还是应用价值都可以提炼作为我们的创新点,最后的语气成果也要明确具体,且要和课题内容紧密相关。

智能AI让学术科研更容易 665

spring MVC 后台token防重复提交解决方案

spring MVC 后台token防重复提交解决方案

kodmoqn的博客 93

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

spring mvc基于token防止重复提交验证

spring mvc基于token防止重复提交验证 实现思路: 在springmvc配置文件中加入拦截器的配置,拦截两类请求,一类是到页面的,一类是提交表单的。当转到页面的请求到来时,生成token的名字和token值,放入session,在页面表单的隐藏域显示。 当表单请求提交时,拦截器得到参数中的tokenName和token,然后到session中去取token值,如果能匹配上,请求就

Java__han的博客 2245

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

关于表单防重复提交一些东东

前阵子弄了些表单防重复提交的东西,想整理整理,免得下次要用时再四处去找,其实这里的东西还是挺简单的。原理:在Session中保存一个表单的唯一编号,将该编号放在一个隐藏域中,同其他数据一同提交。在提交表单后,通过拦截器或其他机制检查唯一编号,如果存在则说明表单是第一次提交,如果不存在则被重复提交(理由很简单,在第一次提交检查后就会从Session中移除该编号)。保存编号可以用一个 HashMap。

DigitalSonic的自留地 9998

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

java请求参数防修改_Spring MVC接口防数据篡改和重复提交

本文实例为大家分享了Spring MVC接口防数据篡改和重复提交的具体代码,供大家参考,具体内容如下一、自定义一个注解,此注解可以使用在方法上或类上使用在方法上,表示此方法需要数据校验使用在类上,表示此类下的所有方法需要数据校验此注解对无参数方法不起作用import org.springframework.stereotype.Component;@Target({ElementType.TYPE...

weixin_28877505的博客 1425

Spring MVC表单防重复提交

利用Spring MVC的过滤器及token传递验证来实现表单防重复提交。 创建注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Token { boolean creat...

a632372394的博客 197

Token注解防止表单的重复提交

注解的一些基础: 参见java注解(一)和java注解(二) 1、自定义一个注解@Token 用来标记需要防止重复提交的方法 package com.bjca.framework.util; /** *关于这个方法的用法是: *在需要生成token的controller上增加@Token(save=true), *而在需要检查重复提交的controller上添加@Token(remove=t...

日拱一卒 908

spring mvc 防止重复提交 token

原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过

u010961759的专栏 1957

spring MVC 基于注解的防止多次提交Token

注:防止多次提交顾名思义,就是防止用户对一个事件进行连续的对此操作,其主要用户数据的添加和更新。使用Token的主要原因是因为http协议交互存在响应时差。 第一步:编写注解Token import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annota

qq_21050783的博客 415

javaweb防重复提交的几种方式

本文针对javaweb项目中防止重复提交几种方式做简单整理。 重复提交场景: 点击提交按钮两次。 点击刷新按钮。 使用浏览器后退按钮重复之前的操作,导致重复提交表单。 使用浏览器历史记录重复提交表单。 浏览器重复的 HTTP 请求。 多人同时时间对同一笔单据进行操作。 方式一:通过JavaScript屏蔽提交按钮 通过js代码,当用户点击提交按钮后,屏蔽提交按钮使用户无法点击提交按钮或点击无效,从而实现防止表单重复提交。 ps:js代码很容易被绕过。比如用户通过刷新页面方式,或使用post

峪幽兰 的博客 1605

springmvc下的基于token的防重复提交实现

问题描述: 现在的网站在注册步骤中,由于后台要处理大量信息,造成响应变慢(测试机器性能差也是造成变慢的一个因素),在前端页面提交信息之前,等待后端响应,此时如果用户 再点一次提交按钮,后台会保存多份用户信息。为解决此问题,借鉴了struts2的token思路,在springmvc下实现token。 实现思路: 在springmvc配置文件中加入拦截器的配置,拦截两类请求,一类是到页面的,一

yangchen的专栏 3350

Spring MVC防止数据重复提交

这个Bug的具体情况是这样的,就是在上传视频后,会将数据提交到服务器,而当提交数据后点击浏览器的后退按扭,却又可以再次提交!这显示是不符合逻辑的,造成了数据重复提交。 好的,下面来讲一下如何在Spring MVC里面解决此问题(其它框架也一样,逻辑一样,思想一样,和具体框架没什么关系)。要解决重复提交,有很多办法,比如说在提交完成后redirect一下,也可以用本文提到的使用token的方法

逍遥飞鹤的专栏 2268

Spring MVC防重复提交

如何在Spring MVC里面解决此问题(其它框架也一样,逻辑一样,思想一样,和具体框架没什么关系)。要解决重复提交,有很多办法,比如说在提交完成后redirect一下,也可以用本文提到的使用token的方法(我不使用redirect是因为那样解决不了ajax提交数据或者移动应用提交数据,另一个原因是现在比较通行的方法是使用token,像python里的django框架也是使用token来解决)。

fengshanssd的博客 294
上一篇: 发送log4j/logback 错误日志到邮件的配置
下一篇: springBoot 集成swagger API 指南和demo案例
lify365
博客等级 码龄15年 6粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值