Red de conocimiento informático - Conocimiento informático - Cómo evitar envíos repetidos en Spring MVC

Cómo evitar envíos repetidos en Spring MVC

Cuando se usan tokens, la lógica del uso de tokens es agregar un interceptor a todas las URL, usar un UUID de Java para generar un UUID aleatorio en el interceptor y colocar este UUID en la sesión, y luego enviar este UUID cuando el navegador envía datos. servidor.

Después de que el servidor recibe el UUID, verifica si el UUID se ha enviado, si se ha enviado, no permite que la lógica continúe...

Bien, entremos en el código real, esto es probablemente el mejor profesor:

Código del token de comentario:

@Target( ElementType.RUNTIME)

Token público @ interface {

boolean save() predeterminado falso;

boolean remove() predeterminado false;

}

Código Interceptor TokenInterceptor:

clase pública TokenInterceptor extiende HandlerInterceptorAdapter {

@Override

public boolean preHandle (solicitud HttpServletRequest, respuesta HttpServletResponse, controlador de objetos) lanza una excepción {

if (instancia del controlador de HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) controlador;

Método método = handlerMethod.getMethod();

Anotación de token = método.getAnnotation( Token.class);

if (annotation ! = null) {

boolean needSaveSession = annotation.save();

if (needSaveSession) {

solicitud .getSession( false).setAttribute(" token", UUID.randomUUID().toString());

}

booleano needRemoveSession = annotation.remove();

if (needRemoveSession) {

if (isRepeatSubmit(solicitud)) {

return false;

}

solicitud .getSession( false).removeAttribute("token");

}

}

devuelve verdadero;

} else {

return super.preHandle(solicitud, respuesta, controlador);

}

}

}

privado boolean isRepeatSubmit( solicitud HttpServletRequest) {

String serverToken = (String) request.getSession(false).getAttribute("token"); if (serverToken == null) {

devuelve verdadero;

>

}

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

if (clinetToken == null ) {

return true;

}

if (!serverToken.equals(clinetToken)) {

devuelve verdadero;

}

Devuelve falso;

}

}

clase pública TokenInterceptor extiende HandlerInterceptorAdapter {

@Override

público booleano preHandle (solicitud HttpServletRequest , respuesta HttpServletResponse, controlador de objetos) arroja una excepción {

if (handler instancia de HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) controlador;

método método = handlerMethod .

getAnnotation(Token.class);

if (annotation! = null) {

boolean needSaveSession = annotation.save();

if (needSaveSession) {

request.getSession(false).setAttribute(" token", UUID.randomUUID().toString());

}

booleano needRemoveSession = anotación .remove();

if (needRemoveSession) {

if (isRepeatSubmit(solicitud)) {

return false;

}

request.getSession(false).getSession(false).getAttribute("token");

if (serverToken == null) {

return true ;

}

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

if (clinetToken == null ) {

devuelve verdadero;

}

if (!serverToken.equals(clinetToken)) {

devuelve verdadero;

}

Devuelve falso;

}

}

Luego agrega el archivo de configuración de Spring MVC:

< mvc :interceptores>

< / mvc:interceptor>

&l

t;bean class="com. storezhang.video.shiro.ShiroInterceptor"/>

El código relevante ha sido comentó Déjalo, creo que puedes entenderlo.

Acerca del uso de este método: simplemente agregue @Token(save=true) en el controlador que necesita generar el token y agregue @Token(remove=true) en el controlador que necesita verificar envíos duplicados).

Además, debe agregar el siguiente código al formulario en la vista:

Una vez completado, continúe intentando ver si puede Aún así volver a enviar los datos.