原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。
1.新建注解:
/** * <p> * 防止重复提交注解,用于方法上<br/> * 在新建页面方法上,设置needSaveToken()为true,此时拦截器会在Session中保存一个token, * 同时需要在新建的页面中添加 * <input type="hidden" name="token" value="${token}"> * <br/> * 保存方法需要验证重复提交的,设置needRemoveToken为true * 此时会在拦截器中验证是否重复提交 * </p> * @author: chuanli * @date: 2013-6-27上午11:14:02 * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AvoidDuplicateSubmission { boolean needSaveToken() default false; boolean needRemoveToken() default false; }
2. 新建拦截器
/** * <p> * 防止重复提交过滤器 * </p> * * @author: chuanli * @date: 2013-6-27上午11:19:05 */ public class AvoidDuplicateSubmissionInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = Logger.getLogger(AvoidDuplicateSubmissionInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { User user = UserUtil.getUser(); if (user != null) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); AvoidDuplicateSubmission annotation = method.getAnnotation(AvoidDuplicateSubmission.class); if (annotation != null) { boolean needSaveSession = annotation.needSaveToken(); if (needSaveSession) { request.getSession(false).setAttribute("token", TokenProcessor.getInstance().generateToken()); } boolean needRemoveSession = annotation.needRemoveToken(); if (needRemoveSession) { if (isRepeatSubmit(request)) { LOG.warn("please don't repeat submit,[user:" + user.getUsername() + ",url:" + request.getServletPath() + "]"); return false; } request.getSession(false).removeAttribute("token"); } } } return true; } private boolean isRepeatSubmit(HttpServletRequest request) { String serverToken = (String) request.getSession(false).getAttribute("token"); if (serverToken == null) { return true; } String clinetToken = request.getParameter("token"); if (clinetToken == null) { return true; } if (!serverToken.equals(clinetToken)) { return true; } return false; } }
3. 在Spring中配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <list> <bean class="com.sohu.tv.crm.aop.UserLogInterceptor"/> <bean class="com.sohu.tv.crm.aop.AvoidDuplicateSubmissionInterceptor"/> </list> </property> </bean>
4. 在相关方法中加入注解:
@RequestMapping("/save") @AvoidDuplicateSubmission(needRemoveToken = true) public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response) throws Exception { @RequestMapping("/edit") @AvoidDuplicateSubmission(needSaveToken = true) public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception {
4. 在相关方法中加入注解:
@RequestMapping("/save") @AvoidDuplicateSubmission(needRemoveToken = true) public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response) throws Exception { @RequestMapping("/edit") @AvoidDuplicateSubmission(needSaveToken = true) public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception {
5.在新建页面中加入
<input type="hidden" name="token" value="${token}">
相关推荐
在实际开发中,我们还会用到Spring的其他功能,比如Spring MVC的拦截器(Interceptor)用于全局处理,`@ExceptionHandler`注解处理异常,以及Spring的单元测试支持。同时,我们还会关注性能优化,如缓存机制(如使用...
综上所述,"spring mvc+mybatis+oracle+jquery easy ui实现增删改查,带拦截器"的项目结合了现代Web开发中的多个核心技术,构建了一个完整的业务处理流程,从用户界面交互到数据库操作,再到安全控制,实现了高效且...
1. **web.xml**:配置DispatcherServlet,包括初始化参数、拦截器、监听器等。 2. **spring-mvc.xml**:定义Bean、数据源、事务管理器、视图解析器、HandlerMapping和HandlerAdapter等。 四、Spring MVC 原理 1. *...
Spring 注解方式防止重复提交原理是通过使用注解和拦截器来实现防止重复提交的。该方法可以防止用户重复提交表单,以提高系统的安全性和可靠性。 2. 使用 Token 防止重复提交 使用 Token 防止重复提交是一种常用...
Spring MVC还支持数据绑定、表单验证、本地化和拦截器等特性,增强了应用的可扩展性和易用性。 **MyBatis** MyBatis是一个优秀的持久层框架,它简化了Java与数据库之间的交互,避免了传统的JDBC代码的繁琐。MyBatis...
- 配置Spring MVC和Spring,设置拦截器、过滤器等。 - 进行单元测试和集成测试,确保功能正常。 这个项目涵盖了Java Web开发中的许多重要概念和技术,对于理解MVC架构、ORM框架以及电子商务系统的设计和实现具有...
在Spring MVC框架中,拦截器(HandlerInterceptor)是一种强大的机制,用于在请求处理前后执行自定义逻辑。它们在控制器方法执行之前和之后运行,提供了一种灵活的方式来添加全局行为,如认证、授权、日志记录、性能...
Spring MVC 是一个基于Java的轻量级Web应用框架,它为构建模型-视图-控制器(MVC)架构的应用程序提供了强大的支持。Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分...
此外,Spring MVC 还支持拦截器(Interceptor),它们可以全局地处理请求和响应,如记录日志、权限检查等。`@ModelAttribute` 注解可以用于将数据从模型绑定到视图,或者从请求参数中提取数据到方法参数。 最后,...
4. 实现Spring MVC的拦截器,进行权限控制和日志记录。 5. 集成Spring Data JPA或MyBatis的Mapper,实现更高级的数据访问功能。 6. 整合Spring Security或Shiro进行安全控制,保护敏感资源。 7. 使用Spring MVC的...
3. **Spring的拦截器(Interceptor)**:可以自定义拦截器,实现`HandlerInterceptor`接口,其中的`postHandle()`方法可以用来处理表单提交后的状态,防止重复提交。 4. **令牌(Token)机制**:与Servlet中的令牌...
在Struts2中,Action类是业务逻辑的载体,配置在struts.xml文件中,通过拦截器链来处理请求和响应。Struts2还提供了丰富的结果类型,如dispatcher(转发)和stream(流式下载),以及强大的OGNL表达式语言,用于在...
Spring Boot整合了Spring MVC,因此我们可以利用Spring MVC的拦截器来实现各种功能,如权限验证、日志记录、性能监控等。本文将详细介绍如何在Spring Boot中设置拦截器,并通过四个基本的HTTP请求方法(PUT、DELETE...
表单提交的数据可以直接绑定到控制器方法的参数上,通过@ModelAttribute注解实现。Hibernate Validator或JSR-303/JSR-349规范的验证可以集成到模型属性的验证中,确保输入数据的有效性。 拦截器(Interceptor)是...
2. **配置Spring MVC**: 配置DispatcherServlet,设置拦截器、视图解析器等。 3. **配置MyBatis**: 编写Mapper XML文件,定义SQL语句,并在Mapper接口上使用注解或XML进行绑定。 4. **创建Mapper接口**: 在Spring ...
为了实现这些功能,Spring MVC的配置文件(如servlet-context.xml)需要正确配置组件扫描、视图解析器、拦截器等。不过,现代Spring MVC项目往往倾向于使用Java配置或Spring Boot的自动配置,减少了XML的使用。 在...
5. **配置SpringMVC**:创建SpringMVC的配置文件,如 servlet-context.xml,配置DispatcherServlet、视图解析器、拦截器等。 6. **配置MyBatis**:创建MyBatis的全局配置文件mybatis-config.xml,以及Mapper接口和...
- **允许其他MVC实现**:Spring MVC 支持多种不同的 MVC 实现,这为开发者提供了更多的选择性。 - **DispatcherServlet**:这是 Spring MVC 的前端控制器,负责接收 HTTP 请求并分发给合适的后端组件处理。 - **...
《网上书城 Spring-MVC》项目是基于Spring-MVC框架构建的一个典型电子商务平台,它展示了如何使用Spring-MVC来实现高效、灵活的Web应用程序开发。Spring-MVC是Spring框架的一部分,专门用于处理Web层的业务,提供了...