Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
532daf62
提交
532daf62
authored
3月 18, 2019
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
后端:增加管理员访问日志
上级
bb612cac
全部展开
显示空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
483 行增加
和
2 行删除
+483
-2
MVCConfiguration.java
...coder/mall/admin/application/config/MVCConfiguration.java
+4
-2
AdminAccessLogInterceptor.java
...mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java
+78
-0
AdminSecurityInterceptor.java
.../mall/admin/sdk/interceptor/AdminSecurityInterceptor.java
+7
-0
AdminAccessLogService.java
...java/cn/iocoder/mall/admin/api/AdminAccessLogService.java
+13
-0
AdminService.java
...src/main/java/cn/iocoder/mall/admin/api/AdminService.java
+3
-0
AdminAccessLogAddDTO.java
...a/cn/iocoder/mall/admin/api/dto/AdminAccessLogAddDTO.java
+133
-0
AdminAccessLogConvert.java
.../cn/iocoder/mall/admin/convert/AdminAccessLogConvert.java
+18
-0
AdminAccessLogMapper.java
.../java/cn/iocoder/mall/admin/dao/AdminAccessLogMapper.java
+11
-0
AdminAccessLogDO.java
...va/cn/iocoder/mall/admin/dataobject/AdminAccessLogDO.java
+133
-0
AdminAccessLogServiceImpl.java
...iocoder/mall/admin/service/AdminAccessLogServiceImpl.java
+57
-0
AdminAccessLogMapper.xml
...e-impl/src/main/resources/mapper/AdminAccessLogMapper.xml
+21
-0
HttpUtil.java
.../main/java/cn/iocoder/common/framework/util/HttpUtil.java
+0
-0
StringUtil.java
...ain/java/cn/iocoder/common/framework/util/StringUtil.java
+5
-0
没有找到文件。
admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/config/MVCConfiguration.java
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
application
.
config
;
package
cn
.
iocoder
.
mall
.
admin
.
application
.
config
;
import
cn.iocoder.common.framework.config.GlobalExceptionHandler
;
import
cn.iocoder.common.framework.config.GlobalExceptionHandler
;
import
cn.iocoder.mall.admin.sdk.interceptor.AdminAccessLogInterceptor
;
import
cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor
;
import
cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
...
@@ -18,16 +19,17 @@ public class MVCConfiguration implements WebMvcConfigurer {
...
@@ -18,16 +19,17 @@ public class MVCConfiguration implements WebMvcConfigurer {
@Autowired
@Autowired
private
AdminSecurityInterceptor
adminSecurityInterceptor
;
private
AdminSecurityInterceptor
adminSecurityInterceptor
;
@Autowired
private
AdminAccessLogInterceptor
adminAccessLogInterceptor
;
//
//
@Override
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
// registry.addInterceptor(securityInterceptor).addPathPatterns("/user/**", "/admin/**"); // 只拦截我们定义的接口
// registry.addInterceptor(securityInterceptor).addPathPatterns("/user/**", "/admin/**"); // 只拦截我们定义的接口
registry
.
addInterceptor
(
adminAccessLogInterceptor
).
addPathPatterns
(
"/admins/**"
);
registry
.
addInterceptor
(
adminSecurityInterceptor
).
addPathPatterns
(
"/admins/**"
)
registry
.
addInterceptor
(
adminSecurityInterceptor
).
addPathPatterns
(
"/admins/**"
)
.
excludePathPatterns
(
"/admins/passport/login"
);
// 排除登陆接口
.
excludePathPatterns
(
"/admins/passport/login"
);
// 排除登陆接口
}
}
@Override
@Override
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
// 解决 swagger-ui.html 的访问,参考自 https://stackoverflow.com/questions/43545540/swagger-ui-no-mapping-found-for-http-request 解决
// 解决 swagger-ui.html 的访问,参考自 https://stackoverflow.com/questions/43545540/swagger-ui-no-mapping-found-for-http-request 解决
...
...
admin/admin-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
sdk
.
interceptor
;
import
cn.iocoder.common.framework.util.HttpUtil
;
import
cn.iocoder.mall.admin.api.AdminAccessLogService
;
import
cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
com.alibaba.fastjson.JSON
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.Date
;
/**
* 访问日志拦截器
*/
@Component
public
class
AdminAccessLogInterceptor
extends
HandlerInterceptorAdapter
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
/**
* 开始时间
*/
private
static
final
ThreadLocal
<
Date
>
START_TIME
=
new
ThreadLocal
<>();
/**
* 管理员编号
*/
private
static
final
ThreadLocal
<
Integer
>
ADMIN_ID
=
new
ThreadLocal
<>();
@Reference
private
AdminAccessLogService
adminAccessLogService
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
// 记录当前时间
START_TIME
.
set
(
new
Date
());
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
{
AdminAccessLogAddDTO
accessLog
=
new
AdminAccessLogAddDTO
();
try
{
accessLog
.
setAdminId
(
ADMIN_ID
.
get
());
if
(
accessLog
.
getAdminId
()
==
null
)
{
accessLog
.
setAdminId
(
AdminAccessLogAddDTO
.
ADMIN_ID_NULL
);
}
accessLog
.
setUri
(
request
.
getRequestURI
());
// TODO 提升:如果想要优化,可以使用 Swagger 的 @ApiOperation 注解。
accessLog
.
setQueryString
(
HttpUtil
.
buildQueryString
(
request
));
accessLog
.
setMethod
(
request
.
getMethod
());
accessLog
.
setUserAgent
(
HttpUtil
.
getUserAgent
(
request
));
accessLog
.
setIp
(
HttpUtil
.
getIp
(
request
));
accessLog
.
setStartTime
(
START_TIME
.
get
());
accessLog
.
setResponseTime
((
int
)
(
System
.
currentTimeMillis
()
-
accessLog
.
getStartTime
().
getTime
()));
// 默认响应时间设为0
adminAccessLogService
.
addAdminAccessLog
(
accessLog
);
// TODO 提升:暂时不考虑 ELK 的方案。而是基于 MySQL 存储。如果访问日志比较多,需要定期归档。
}
catch
(
Throwable
th
)
{
logger
.
error
(
"[afterCompletion][插入管理员访问日志({}) 发生异常({})"
,
JSON
.
toJSONString
(
accessLog
),
ExceptionUtils
.
getRootCauseMessage
(
th
));
}
finally
{
clear
();
}
}
public
static
void
setAdminId
(
Integer
adminId
)
{
ADMIN_ID
.
set
(
adminId
);
}
public
static
void
clear
()
{
START_TIME
.
remove
();
ADMIN_ID
.
remove
();
}
}
admin/admin-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminSecurityInterceptor.java
浏览文件 @
532daf62
...
@@ -39,6 +39,13 @@ public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
...
@@ -39,6 +39,13 @@ public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
// 添加到 AdminSecurityContext
// 添加到 AdminSecurityContext
AdminSecurityContext
context
=
new
AdminSecurityContext
(
authentication
.
getAdminId
(),
authentication
.
getRoleIds
());
AdminSecurityContext
context
=
new
AdminSecurityContext
(
authentication
.
getAdminId
(),
authentication
.
getRoleIds
());
AdminSecurityContextHolder
.
setContext
(
context
);
AdminSecurityContextHolder
.
setContext
(
context
);
// 同时也记录管理员编号到 AdminAccessLogInterceptor 中。因为:
// AdminAccessLogInterceptor 需要在 AdminSecurityInterceptor 之前执行,这样记录的访问日志才健全
// AdminSecurityInterceptor 执行后,会移除 AdminSecurityContext 信息,这就导致 AdminAccessLogInterceptor 无法获得管理员编号
// 因此,这里需要进行记录
if
(
authentication
.
getAdminId
()
!=
null
)
{
AdminAccessLogInterceptor
.
setAdminId
(
authentication
.
getAdminId
());
}
}
else
{
}
else
{
String
url
=
request
.
getRequestURI
();
String
url
=
request
.
getRequestURI
();
if
(!
url
.
equals
(
"/admin/passport/login"
))
{
// TODO 临时写死。非登陆接口,必须已经认证身份,不允许匿名访问
if
(!
url
.
equals
(
"/admin/passport/login"
))
{
// TODO 临时写死。非登陆接口,必须已经认证身份,不允许匿名访问
...
...
admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/AdminAccessLogService.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
api
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO
;
/**
* 管理员访问日志 Service 接口
*/
public
interface
AdminAccessLogService
{
CommonResult
<
Boolean
>
addAdminAccessLog
(
AdminAccessLogAddDTO
adminAccessLogAddDTO
);
}
admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/AdminService.java
浏览文件 @
532daf62
...
@@ -9,6 +9,9 @@ import cn.iocoder.mall.admin.api.dto.AdminUpdateDTO;
...
@@ -9,6 +9,9 @@ import cn.iocoder.mall.admin.api.dto.AdminUpdateDTO;
import
java.util.Set
;
import
java.util.Set
;
/**
* 管理员 Service 接口
*/
public
interface
AdminService
{
public
interface
AdminService
{
CommonResult
<
AdminPageBO
>
getAdminPage
(
AdminPageDTO
adminPageDTO
);
CommonResult
<
AdminPageBO
>
getAdminPage
(
AdminPageDTO
adminPageDTO
);
...
...
admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/AdminAccessLogAddDTO.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
api
.
dto
;
import
javax.validation.constraints.NotNull
;
import
java.util.Date
;
/**
* 管理员访问日志添加 DTO
*/
public
class
AdminAccessLogAddDTO
{
/**
* 管理员编号 - 空
*/
public
static
final
Integer
ADMIN_ID_NULL
=
0
;
/**
* 管理员编号.
*
* 当管理员为空时,该值为0
*/
@NotNull
(
message
=
"管理员编号不能为空"
)
private
Integer
adminId
;
/**
* 访问地址
*/
@NotNull
(
message
=
"访问地址不能为空"
)
private
String
uri
;
/**
* 参数
*/
@NotNull
(
message
=
"请求参数不能为空"
)
private
String
queryString
;
/**
* http 方法
*/
@NotNull
(
message
=
"http 请求方法不能为空"
)
private
String
method
;
/**
* User Agent
*/
@NotNull
(
message
=
"User-Agent 不能为空"
)
private
String
userAgent
;
/**
* ip
*/
@NotNull
(
message
=
"ip 不能为空"
)
private
String
ip
;
/**
* 请求时间
*/
@NotNull
(
message
=
"请求时间不能为空"
)
private
Date
startTime
;
/**
* 响应时长 -- 毫秒级
*/
@NotNull
(
message
=
"响应时长不能为空"
)
private
Integer
responseTime
;
public
Integer
getAdminId
()
{
return
adminId
;
}
public
AdminAccessLogAddDTO
setAdminId
(
Integer
adminId
)
{
this
.
adminId
=
adminId
;
return
this
;
}
public
String
getUri
()
{
return
uri
;
}
public
AdminAccessLogAddDTO
setUri
(
String
uri
)
{
this
.
uri
=
uri
;
return
this
;
}
public
String
getQueryString
()
{
return
queryString
;
}
public
AdminAccessLogAddDTO
setQueryString
(
String
queryString
)
{
this
.
queryString
=
queryString
;
return
this
;
}
public
String
getMethod
()
{
return
method
;
}
public
AdminAccessLogAddDTO
setMethod
(
String
method
)
{
this
.
method
=
method
;
return
this
;
}
public
String
getUserAgent
()
{
return
userAgent
;
}
public
AdminAccessLogAddDTO
setUserAgent
(
String
userAgent
)
{
this
.
userAgent
=
userAgent
;
return
this
;
}
public
String
getIp
()
{
return
ip
;
}
public
AdminAccessLogAddDTO
setIp
(
String
ip
)
{
this
.
ip
=
ip
;
return
this
;
}
public
Date
getStartTime
()
{
return
startTime
;
}
public
AdminAccessLogAddDTO
setStartTime
(
Date
startTime
)
{
this
.
startTime
=
startTime
;
return
this
;
}
public
Integer
getResponseTime
()
{
return
responseTime
;
}
public
AdminAccessLogAddDTO
setResponseTime
(
Integer
responseTime
)
{
this
.
responseTime
=
responseTime
;
return
this
;
}
}
\ No newline at end of file
admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/AdminAccessLogConvert.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
convert
;
import
cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO
;
import
cn.iocoder.mall.admin.dataobject.AdminAccessLogDO
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mappings
;
import
org.mapstruct.factory.Mappers
;
@Mapper
public
interface
AdminAccessLogConvert
{
AdminAccessLogConvert
INSTANCE
=
Mappers
.
getMapper
(
AdminAccessLogConvert
.
class
);
@Mappings
({})
AdminAccessLogDO
convert
(
AdminAccessLogAddDTO
adminAccessLogAddDTO
);
}
\ No newline at end of file
admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminAccessLogMapper.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
dao
;
import
cn.iocoder.mall.admin.dataobject.AdminAccessLogDO
;
import
org.springframework.stereotype.Repository
;
@Repository
public
interface
AdminAccessLogMapper
{
void
insert
(
AdminAccessLogDO
entity
);
}
admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminAccessLogDO.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
dataobject
;
import
cn.iocoder.common.framework.dataobject.BaseDO
;
import
java.util.Date
;
/**
* 管理员访问日志 DO
*/
public
class
AdminAccessLogDO
extends
BaseDO
{
/**
* 编号
*/
private
Integer
id
;
/**
* 管理员编号.
*
* 当管理员为空时,该值为0
*/
private
Integer
adminId
;
/**
* 访问地址
*/
private
String
uri
;
/**
* 参数
*/
private
String
queryString
;
/**
* http 方法
*/
private
String
method
;
/**
* userAgent
*/
private
String
userAgent
;
/**
* ip
*/
private
String
ip
;
/**
* 请求时间
*/
private
Date
startTime
;
/**
* 响应时长 -- 毫秒级
*/
private
Integer
responseTime
;
public
Integer
getId
()
{
return
id
;
}
public
AdminAccessLogDO
setId
(
Integer
id
)
{
this
.
id
=
id
;
return
this
;
}
public
Integer
getAdminId
()
{
return
adminId
;
}
public
AdminAccessLogDO
setAdminId
(
Integer
adminId
)
{
this
.
adminId
=
adminId
;
return
this
;
}
public
String
getUri
()
{
return
uri
;
}
public
AdminAccessLogDO
setUri
(
String
uri
)
{
this
.
uri
=
uri
;
return
this
;
}
public
String
getQueryString
()
{
return
queryString
;
}
public
AdminAccessLogDO
setQueryString
(
String
queryString
)
{
this
.
queryString
=
queryString
;
return
this
;
}
public
String
getMethod
()
{
return
method
;
}
public
AdminAccessLogDO
setMethod
(
String
method
)
{
this
.
method
=
method
;
return
this
;
}
public
String
getUserAgent
()
{
return
userAgent
;
}
public
AdminAccessLogDO
setUserAgent
(
String
userAgent
)
{
this
.
userAgent
=
userAgent
;
return
this
;
}
public
String
getIp
()
{
return
ip
;
}
public
AdminAccessLogDO
setIp
(
String
ip
)
{
this
.
ip
=
ip
;
return
this
;
}
public
Date
getStartTime
()
{
return
startTime
;
}
public
AdminAccessLogDO
setStartTime
(
Date
startTime
)
{
this
.
startTime
=
startTime
;
return
this
;
}
public
Integer
getResponseTime
()
{
return
responseTime
;
}
public
AdminAccessLogDO
setResponseTime
(
Integer
responseTime
)
{
this
.
responseTime
=
responseTime
;
return
this
;
}
}
\ No newline at end of file
admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminAccessLogServiceImpl.java
0 → 100644
浏览文件 @
532daf62
package
cn
.
iocoder
.
mall
.
admin
.
service
;
import
cn.iocoder.common.framework.util.StringUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.admin.api.AdminAccessLogService
;
import
cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO
;
import
cn.iocoder.mall.admin.convert.AdminAccessLogConvert
;
import
cn.iocoder.mall.admin.dao.AdminAccessLogMapper
;
import
cn.iocoder.mall.admin.dataobject.AdminAccessLogDO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.Date
;
@Service
@com
.
alibaba
.
dubbo
.
config
.
annotation
.
Service
(
validation
=
"true"
)
public
class
AdminAccessLogServiceImpl
implements
AdminAccessLogService
{
/**
* 请求参数最大长度。
*/
private
static
final
Integer
QUERY_STRING_MAX_LENGTH
=
4096
;
/**
* 请求地址最大长度。
*/
private
static
final
Integer
URI_MAX_LENGTH
=
4096
;
/**
* User-Agent 最大长度。
*/
private
static
final
Integer
USER_AGENT_MAX_LENGTH
=
1024
;
@Autowired
private
AdminAccessLogMapper
adminAccessLogMapper
;
@Override
public
CommonResult
<
Boolean
>
addAdminAccessLog
(
AdminAccessLogAddDTO
adminAccessLogAddDTO
)
{
// 创建 AdminAccessLogDO
AdminAccessLogDO
accessLog
=
AdminAccessLogConvert
.
INSTANCE
.
convert
(
adminAccessLogAddDTO
);
accessLog
.
setCreateTime
(
new
Date
());
// 截取最大长度
if
(
accessLog
.
getUri
().
length
()
>
URI_MAX_LENGTH
)
{
accessLog
.
setUri
(
StringUtil
.
substring
(
accessLog
.
getUri
(),
URI_MAX_LENGTH
));
}
if
(
accessLog
.
getQueryString
().
length
()
>
QUERY_STRING_MAX_LENGTH
)
{
accessLog
.
setQueryString
(
StringUtil
.
substring
(
accessLog
.
getQueryString
(),
QUERY_STRING_MAX_LENGTH
));
}
if
(
accessLog
.
getUserAgent
().
length
()
>
USER_AGENT_MAX_LENGTH
)
{
accessLog
.
setUserAgent
(
StringUtil
.
substring
(
accessLog
.
getUserAgent
(),
USER_AGENT_MAX_LENGTH
));
}
// 插入
adminAccessLogMapper
.
insert
(
accessLog
);
// 返回成功
return
CommonResult
.
success
(
true
);
}
}
\ No newline at end of file
admin/admin-service-impl/src/main/resources/mapper/AdminAccessLogMapper.xml
0 → 100644
浏览文件 @
532daf62
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.mall.admin.dao.AdminAccessLogMapper"
>
<!--<sql id="FIELDS">-->
<!--id, username, nickname, password, status,-->
<!--create_time-->
<!--</sql>-->
<insert
id=
"insert"
parameterType=
"AdminAccessLogDO"
useGeneratedKeys=
"true"
keyColumn=
"id"
keyProperty=
"id"
>
INSERT INTO admin_access_log (
admin_id, uri, query_string, method, user_agent,
ip, start_time, response_time, create_time
) VALUES (
#{adminId}, #{uri}, #{queryString}, #{method}, #{userAgent},
#{ip}, #{startTime}, #{responseTime}, #{createTime}
)
</insert>
</mapper>
\ No newline at end of file
common/common-framework/src/main/java/cn/iocoder/common/framework/util/HttpUtil.java
浏览文件 @
532daf62
差异被折叠。
点击展开。
common/common-framework/src/main/java/cn/iocoder/common/framework/util/StringUtil.java
浏览文件 @
532daf62
...
@@ -27,4 +27,8 @@ public class StringUtil {
...
@@ -27,4 +27,8 @@ public class StringUtil {
return
array
;
return
array
;
}
}
public
static
String
substring
(
String
str
,
int
start
)
{
return
org
.
apache
.
commons
.
lang3
.
StringUtils
.
substring
(
str
,
start
);
}
}
}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论