好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java后端限制频繁请求和重复提交的实现

当前端按连续请求多次,请求过于频繁或者是多次重复提交数据,对系统或者是数据造成了一点的损害。

为了解决这个问题,下面介绍了一种简易的解决方法:

步骤一、写限制注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

/**

  * @Author Minco

  * @Date 16:04 2020-08-13

  * @Description 不重复提交注解

  */

 

@Target (ElementType.METHOD) // 作用到方法上

@Retention (RetentionPolicy.RUNTIME) // 运行时有效

public @interface NoRepeatSubmit {

 

     String name() default "name:" ;

}

步骤二、解析注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

import javax.servlet.http.HttpServletRequest;

import com.hieasy.comm.core.domain.R;

import com.hieasy.comm.redis.service.RedisService;

import com.hieasy.system.util.TermUtil;

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.stereotype.Component;

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

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

import java.util.concurrent.TimeUnit;

 

 

/**

  * @Author Minco

  * @Date 16:02 2020-08-13

  * @Description aop解析注解

  */

 

@Aspect

@Component

public class NoRepeatSubmitAop {

 

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

 

     @Autowired

     private RedisService redisService;

 

     @Around ( "execution(* com.hieasy.*.controller.*.*Ctrl.*(..)) && @annotation(nrs)" )

     public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) throws Throwable {

       

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

             HttpServletRequest request = attributes.getRequest();

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

             if ( !redisService.haskey(key) ) { // 如果缓存中有这个url视为重复提交

                 Object o = pjp.proceed();

                 redisService.setCacheObject(key, 0 , 15 , TimeUnit.SECONDS);

                 return o;

             } else {

                 redisService.setCacheObject(key, 0 , 15 , TimeUnit.SECONDS); //点了同样的URL继续限制,直到2次点击中间间隔超过了限制

                 return R.error( "请勿重复提交或者操作过于频繁!" );

             }

    

     }

 

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

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

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

import org.springframework.stereotype.Component;

 

import java.util.*;

import java.util.concurrent.TimeUnit;

 

/**

  * @Author Minco

  * @Date 13:55 2020-06-23

  * @Description RedisService

  */

@Component

@SuppressWarnings (value = { "unchecked" , "rawtypes" })

public class RedisService {

 

     @Autowired

     public RedisTemplate redisTemplate;

 

     /**

      * 缓存基本的对象,Integer、String、实体类等

      *

      * @param key   缓存的键值

      * @param value 缓存的值

      * @return 缓存的对象

      */

     public <T> ValueOperations<String, T> setCacheObject(String key, T value) {

         ValueOperations<String, T> operation = redisTemplate.opsForValue();

         operation.set(key, value);

         return operation;

     }

 

     /**

      * 缓存基本的对象,Integer、String、实体类等

      *

      * @param key      缓存的键值

      * @param value    缓存的值

      * @param timeout  时间

      * @param timeUnit 时间颗粒度

      * @return 缓存的对象

      */

     public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) {

         ValueOperations<String, T> operation = redisTemplate.opsForValue();

         operation.set(key, value, timeout, timeUnit);

         return operation;

     }

 

     /**

      * 获得缓存的基本对象。

      *

      * @param key 缓存键值

      * @return 缓存键值对应的数据

      */

     public <T> T getCacheObject(String key) {

         ValueOperations<String, T> operation = redisTemplate.opsForValue();

         return operation.get(key);

     }

 

     /**

      * 删除单个对象

      *

      * @param key

      */

     public void deleteObject(String key) {

         redisTemplate.delete(key);

     }

 

     /**

      * 删除集合对象

      *

      * @param collection

      */

     public void deleteObject(Collection collection) {

         redisTemplate.delete(collection);

     }

 

     /**

      * 缓存List数据

      *

      * @param key      缓存的键值

      * @param dataList 待缓存的List数据

      * @return 缓存的对象

      */

     public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {

         ListOperations listOperation = redisTemplate.opsForList();

         if ( null != dataList) {

             int size = dataList.size();

             for ( int i = 0 ; i < size; i++) {

                 listOperation.leftPush(key, dataList.get(i));

             }

         }

         return listOperation;

     }

 

     /**

      * 获得缓存的list对象

      *

      * @param key 缓存的键值

      * @return 缓存键值对应的数据

      */

     public <T> List<T> getCacheList(String key) {

         List<T> dataList = new ArrayList<T>();

         ListOperations<String, T> listOperation = redisTemplate.opsForList();

         Long size = listOperation.size(key);

 

         for ( int i = 0 ; i < size; i++) {

             dataList.add(listOperation.index(key, i));

         }

         return dataList;

     }

 

     /**

      * 缓存Set

      *

      * @param key     缓存键值

      * @param dataSet 缓存的数据

      * @return 缓存数据的对象

      */

     public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) {

         BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);

         Iterator<T> it = dataSet.iterator();

         while (it.hasNext()) {

             setOperation.add(it.next());

         }

         return setOperation;

     }

 

     /**

      * 获得缓存的set

      *

      * @param key

      * @return

      */

     public <T> Set<T> getCacheSet(String key) {

         Set<T> dataSet = new HashSet<T>();

         BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);

         dataSet = operation.members();

         return dataSet;

     }

 

     /**

      * 缓存Map

      *

      * @param key

      * @param dataMap

      * @return

      */

     public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) {

         HashOperations hashOperations = redisTemplate.opsForHash();

         if ( null != dataMap) {

             for (Map.Entry<String, T> entry : dataMap.entrySet()) {

                 hashOperations.put(key, entry.getKey(), entry.getValue());

             }

         }

         return hashOperations;

     }

 

     /**

      * 获得缓存的Map

      *

      * @param key

      * @return

      */

     public <T> Map<String, T> getCacheMap(String key) {

         Map<String, T> map = redisTemplate.opsForHash().entries(key);

         return map;

     }

 

     /**

      * 获得缓存的基本对象列表

      *

      * @param pattern 字符串前缀

      * @return 对象列表

      */

     public Collection<String> keys(String pattern) {

         return redisTemplate.keys(pattern);

     }

 

     /**

      *

      * @param key

      * @return

      */

     public boolean   haskey(String key){

         return redisTemplate.hasKey(key);

     }

 

     public Long getExpire(String key){

        return redisTemplate.getExpire(key);

     }

 

 

     public <T> ValueOperations<String, T> setBillObject(String key, List<Map<String, Object>> value) {

         ValueOperations<String, T> operation = redisTemplate.opsForValue();

         operation.set(key, (T) value);

         return operation;

     }

     /**

      * 缓存list<Map<String, Object>>

      *

      * @param key      缓存的键值

      * @param value    缓存的值

      * @param timeout  时间

      * @param timeUnit 时间颗粒度

      * @return 缓存的对象

      */

     public <T> ValueOperations<String, T> setBillObject(String key, List<Map<String, Object>> value, Integer timeout, TimeUnit timeUnit) {

         ValueOperations<String, T> operation = redisTemplate.opsForValue();

         operation.set(key,(T)value, timeout, timeUnit);

         return operation;

     }

     /**

      * 缓存Map

      *

      * @param key

      * @param dataMap

      * @return

      */

     public <T> HashOperations<String, String, T> setCKdBillMap(String key, Map<String, T> dataMap) {

         HashOperations hashOperations = redisTemplate.opsForHash();

         if ( null != dataMap) {

             for (Map.Entry<String, T> entry : dataMap.entrySet()) {

                 hashOperations.put(key, entry.getKey(), entry.getValue());

             }

         }

         return hashOperations;

     }

}

步骤三、控制层注解使用

?

1

2

3

4

5

6

7

8

@NoRepeatSubmit

@PostMapping ( "insert" )

@OperLog (title = "仓库调整" , businessType = BusinessType.INSERT)

@ApiOperation (value = "新增仓库调整单" , notes = "" )

public R insert( @RequestBody Cktzd cktzd) {

     System.out.println(JSON.toJSONString(cktzd));

     return R.error( "测试阶段!" );

}

 测试结果:

第一次提交

在不间隔15就继续点

不间断的点,只要2次点击之间没有超过15秒,都会抛出请勿重复请求。直到2次点击之间间隔足够才能正常请求! 

到此这篇关于Java后端限制频繁请求和重复提交的实现的文章就介绍到这了,更多相关Java后端限制频繁请求内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://blog.csdn.net/chengmin123456789/article/details/107982095

查看更多关于Java后端限制频繁请求和重复提交的实现的详细内容...

  阅读:22次