• notice
  • Congratulations on the launch of the Sought Tech site

How does Spring Boot prevent duplicate submissions

How does Spring Boot prevent duplicate submissions

Scenario: The submission of the same URL by the same user within 2 seconds is considered as a duplicate submission.

How does Spring Boot prevent duplicate submissions

Think logic:

1. From the perspective of the database

2. Considering from the application level, first judge whether it is a stand-alone service or a distributed service, then you need to consider some caches at this time, and use the caches to ensure the repeated submission of data.

Assuming it is a distributed application, you can assemble user information, such as token and requested url, and store it in a cache, such as redis, and set the timeout to 2 seconds to ensure the uniqueness of the data.

The following is the code implementation:

http ://

Application.java

package com;


import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;


/**

* @author spring.tsh

* @function description anti-duplicate submission

* @date 2018-08-26

*/

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

application.yml

spring:

redis:

host: 127.0.0.1

port: 6379

password: 123456

RedisConfig.java

package com.common;


import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ConfigrLvbzTRuration;

import org.springframework.data.redis.connection.RedisStandaloneConfiguration;

import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;


@Configuration


public class RedisConfig {

@Bean

@ConfigurationProperties(prefix = "spring.redis")

public JedisConnectionFactory getConnectionFactory() {

return new JedisConnectionFactory(new RedisStandaloneConfiguration(), JedisClientConfiguration.builder().build());

}


@Bean

RedisTemplategetRedisTemplate() {

RedisTemplateredisTemplate = new RedisTemplate();

redisTemplate.setConnectionFactory(getConnectionFactory());

return redisTemplate;

}


}

Custom annotation NoRepeatSubmit.java

package com.common;


import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;


@Target(ElementType.METHOD) // apply to the method

@Retention(RetentionPolicy.RUNTIME) // valid at runtime

/**

* @function description to prevent duplicate submission mark annotation

* @author srping.tsh

* @date 2018-08-26

*/

public @interface NoRepeatSubmit {

}

aop parsing annotation NoRepeatSubmitAop.java

package com.common;


import javax.servlet.http.HttpServletRequest;


import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.ValueOperations;

import org.springframework.stereotype.Component;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;


@Aspect

@Component

/**

* @function description aop parsing annotation

* @author gaozz.club

* @date 2018-11-02rLvbzTR

*/

public class NoRepeatSubmitAop {


private Log logger = LogFactory. getLog(getClass());


@Autowired

private RedisTemplatetemplate;


@Around("execution(* com.example..*Controller.*(..)) && @annotation(nrs)")

public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {

Value OperationsopsForValue = template. opsForValue();

try {

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder. getRequestAttributes();

String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();

HttpServletRequest request = attributes. getRequest();

String key = sessionId + "-" + request. getServletPath();

if (opsForValue.get(key) == null) {// If there is this url in the cache, it will be considered as a duplicate submission

Object o = pjp. proceed();

opsForValue.set(key, 0, 2, TimeUnit.SECONDS);

return o;

} else {

logger.error("Duplicate submission");

return null;

}

} catch (Throwable e) {

e.printStackTrace();

logger.error("An unknown exception occurred when verifying repeated submission!");

return "{\"code\":-889,\"message\":\"An unknown exception occurred when verifying repeated submissions!\"}";

}


}


}

Test class:

package com.example;


import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;


import com.common.NoRepeatSubmit;


/**

* @function description test Controller

* @author spring.tsh

* @date 2018-08-26

*/

@RestController

public class TestController {

@RequestMapping("/test")

@NoRepeatSubmit

public String test() {

return ("program logic return");

}


}


Tags

Technical otaku

Sought technology together

Related Topic

0 Comments

Leave a Reply

+