也是在网上搜的,照着人家的写的,写一次还是印象深刻的。
测试场景大约是这样的,新增用户,保存后依然停留在新增用户页面,数据也依然保留在输入框里,这时再点击 保存就会出现重复保存。
解决问题后,再次点击保存则跳转到列表页面。
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 }">