利用Token解决 springMVC重复提交问题

也是在网上搜的,照着人家的写的,写一次还是印象深刻的。

测试场景大约是这样的,新增用户,保存后依然停留在新增用户页面,数据也依然保留在输入框里,这时再点击 保存就会出现重复保存。

解决问题后,再次点击保存则跳转到列表页面。

1、自定义注解

    

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
	
	boolean save() default false;
	
	boolean remove() default false;
}

2、写个拦截器

package com.cjl.interceptor;

import java.lang.reflect.Method;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.cjl.myAnnotation.Token;

/**
 * 定义个拦截器,用来校验重复提交
 * @author ThinkPad
 *
 */

public class TokenInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("进入拦截器--------");
		if(handler instanceof HandlerMethod)
		{
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();
			Token annotation = method.getAnnotation(Token.class);
			if(annotation != null)
			{
				boolean needSaveSession = annotation.save();
				if(needSaveSession)
				{
					request.getSession(false).setAttribute("token", UUID.randomUUID().toString());
				}
				boolean needRemoveSession = annotation.remove();
				if(needRemoveSession)
				{
					if(isRepeatSubmit(request))
					{
						response.sendRedirect(request.getContextPath()+"/user");
						return false;
					}
					request.getSession(false).removeAttribute("token");
				}
			}
			return true;
		}
		else
		{
			return super.preHandle(request, response, handler);
		}
	}

	/**
	 * true 是重复提交
	 * false 不是重复提交
	 * @param request
	 * @return
	 */
	public boolean isRepeatSubmit(HttpServletRequest request)
	{
		String saveToken = (String) request.getSession(false).getAttribute("token");
		if(saveToken==null)
		{
			return true;
		}
		String clientToken = request.getParameter("token");
		if(clientToken == null)
		{
			return true;
		}
		if(!saveToken.equals(clientToken))
		{
			return true;
		}
		return false;
	}
}

3、配置
<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/input"/>
			<mvc:mapping path="/saveUser"/>
			<bean class="com.cjl.interceptor.TokenInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

4、controller配置上注解

        @Token(save=true)
	@RequestMapping(value="/input",method=RequestMethod.GET)
	public String input(Map<String,Object> map)
	{
		map.put("user", new User());
		return "input";
	}
	
	@Token(remove=true)
	@RequestMapping(value="/saveUser",method=RequestMethod.POST)
	public String saveUser(User user)
	{
		userService.saveUser(user);
		return "input";
	}

在进入表单时配置@Token(save=true),在保存表单时配置@Token(remove=true)

5、JSP页面

<input type="hidden" name="token" value="${token }">

猜你喜欢

转载自blog.csdn.net/xingyuncaojun/article/details/80785542
今日推荐