Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
JAVA小学生-王铁柱
eladmin
提交
a0739f8d
E
eladmin
项目概览
JAVA小学生-王铁柱
/
eladmin
与 Fork 源项目一致
从无法访问的项目Fork
通知
4
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
eladmin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a0739f8d
编写于
12月 28, 2018
作者:
github_28344065
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add limit tag for controller
增加限流注解, 控制接口访问
上级
31042d24
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
192 addition
and
41 deletion
+192
-41
pom.xml
pom.xml
+4
-1
src/main/java/me/zhengjie/common/aop/limit/Limit.java
src/main/java/me/zhengjie/common/aop/limit/Limit.java
+33
-0
src/main/java/me/zhengjie/common/aop/limit/LimitAspect.java
src/main/java/me/zhengjie/common/aop/limit/LimitAspect.java
+85
-0
src/main/java/me/zhengjie/common/aop/limit/LimitType.java
src/main/java/me/zhengjie/common/aop/limit/LimitType.java
+7
-0
src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
+39
-40
src/main/java/me/zhengjie/tools/rest/TestController.java
src/main/java/me/zhengjie/tools/rest/TestController.java
+24
-0
未找到文件。
pom.xml
浏览文件 @
a0739f8d
...
...
@@ -75,7 +75,10 @@
<artifactId>
commons-pool2
</artifactId>
<version>
2.5.0
</version>
</dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
</dependency>
<!--jwt-->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
...
...
src/main/java/me/zhengjie/common/aop/limit/Limit.java
0 → 100644
浏览文件 @
a0739f8d
package
me.zhengjie.common.aop.limit
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author jacky
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
Limit
{
// 资源名称,用于描述接口功能
String
name
()
default
""
;
// 资源 key
String
key
()
default
""
;
// key prefix
String
prefix
()
default
""
;
// 时间的,单位秒
int
period
();
// 限制访问次数
int
count
();
// 限制类型
LimitType
limitType
()
default
LimitType
.
CUSTOMER
;
}
src/main/java/me/zhengjie/common/aop/limit/LimitAspect.java
0 → 100644
浏览文件 @
a0739f8d
package
me.zhengjie.common.aop.limit
;
import
com.google.common.collect.ImmutableList
;
import
me.zhengjie.common.exception.BadRequestException
;
import
me.zhengjie.common.utils.IpUtil
;
import
me.zhengjie.common.utils.RequestHolder
;
import
org.apache.commons.lang3.StringUtils
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.script.DefaultRedisScript
;
import
org.springframework.data.redis.core.script.RedisScript
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
java.lang.reflect.Method
;
@Aspect
@Component
public
class
LimitAspect
{
@Autowired
private
RedisTemplate
redisTemplate
;
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LimitAspect
.
class
);
@Pointcut
(
"@annotation(Limit)"
)
public
void
pointcut
()
{
//
}
@Around
(
"pointcut()"
)
public
Object
around
(
ProceedingJoinPoint
joinPoint
)
throws
Throwable
{
HttpServletRequest
request
=
RequestHolder
.
getHttpServletRequest
();
MethodSignature
signature
=
(
MethodSignature
)
joinPoint
.
getSignature
();
Method
signatureMethod
=
signature
.
getMethod
();
Limit
limit
=
signatureMethod
.
getAnnotation
(
Limit
.
class
);
LimitType
limitType
=
limit
.
limitType
();
String
name
=
limit
.
name
();
String
key
=
limit
.
key
();
if
(
StringUtils
.
isEmpty
(
key
))
{
switch
(
limitType
)
{
case
IP:
key
=
IpUtil
.
getIP
(
request
);
break
;
default
:
key
=
signatureMethod
.
getName
();
}
}
ImmutableList
keys
=
ImmutableList
.
of
(
StringUtils
.
join
(
limit
.
prefix
(),
"_"
,
key
,
"_"
,
request
.
getRequestURI
().
replaceAll
(
"/"
,
"_"
)));
String
luaScript
=
buildLuaScript
();
RedisScript
<
Number
>
redisScript
=
new
DefaultRedisScript
<>(
luaScript
,
Number
.
class
);
Number
count
=
(
Number
)
redisTemplate
.
execute
(
redisScript
,
keys
,
limit
.
count
(),
limit
.
period
());
if
(
null
!=
count
&&
count
.
intValue
()
<=
limit
.
count
())
{
logger
.
info
(
"第{}次访问key为 {},描述为 [{}] 的接口"
,
count
,
keys
,
limit
.
name
());
return
joinPoint
.
proceed
();
}
else
{
throw
new
BadRequestException
(
"访问次数受限制"
);
}
}
/**
* 限流脚本
*/
private
String
buildLuaScript
()
{
return
"local c"
+
"\nc = redis.call('get',KEYS[1])"
+
"\nif c and tonumber(c) > tonumber(ARGV[1]) then"
+
"\nreturn c;"
+
"\nend"
+
"\nc = redis.call('incr',KEYS[1])"
+
"\nif tonumber(c) == 1 then"
+
"\nredis.call('expire',KEYS[1],ARGV[2])"
+
"\nend"
+
"\nreturn c;"
;
}
}
src/main/java/me/zhengjie/common/aop/limit/LimitType.java
0 → 100644
浏览文件 @
a0739f8d
package
me.zhengjie.common.aop.limit
;
public
enum
LimitType
{
CUSTOMER
,
// by ip addr
IP
;
}
src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
浏览文件 @
a0739f8d
...
...
@@ -78,7 +78,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.
antMatchers
(
"/auth/**"
).
permitAll
()
.
antMatchers
(
"/websocket/**"
).
permitAll
()
.
antMatchers
(
"/druid/**"
).
anonymous
()
// swagger start
.
antMatchers
(
"/swagger-ui.html"
).
anonymous
()
...
...
@@ -86,7 +85,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.
antMatchers
(
"/webjars/**"
).
anonymous
()
.
antMatchers
(
"/*/api-docs"
).
anonymous
()
// swagger end
.
antMatchers
(
"/test/**"
).
anonymous
()
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
anonymous
()
// 所有请求都需要认证
...
...
src/main/java/me/zhengjie/tools/rest/TestController.java
0 → 100644
浏览文件 @
a0739f8d
package
me.zhengjie.tools.rest
;
import
me.zhengjie.common.aop.limit.Limit
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.concurrent.atomic.AtomicInteger
;
@RestController
@RequestMapping
(
"test"
)
public
class
TestController
{
private
static
final
AtomicInteger
ATOMIC_INTEGER
=
new
AtomicInteger
();
/**
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test,
*/
@Limit
(
key
=
"test"
,
period
=
60
,
count
=
10
,
name
=
"testLimit"
,
prefix
=
"limit"
)
@GetMapping
(
"limit"
)
public
int
testLimit
()
{
return
ATOMIC_INTEGER
.
incrementAndGet
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录