Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Eladmin
Commits
fd9fb2a6
Commit
fd9fb2a6
authored
Nov 01, 2019
by
dqjdda
Browse files
Merge branch '2.3dev'
parents
7895e547
1839ef8d
Changes
227
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
fd9fb2a6
...
@@ -21,13 +21,12 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
...
@@ -21,13 +21,12 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
| | 后端源码 | 前端源码 |
| | 后端源码 | 前端源码 |
|--- |--- | --- |
|--- |--- | --- |
| github | https://github.com/elunez/eladmin | https://github.com/elunez/eladmin-
qd
|
| github | https://github.com/elunez/eladmin | https://github.com/elunez/eladmin-
web
|
| 码云 | https://gitee.com/elunez/eladmin | https://gitee.com/elunez/eladmin-
qt
|
| 码云 | https://gitee.com/elunez/eladmin | https://gitee.com/elunez/eladmin-
web
|
#### 系统功能
#### 系统功能
-
用户管理:提供用户的相关配置,新增用户后,默认密码为123456
-
用户管理:提供用户的相关配置,新增用户后,默认密码为123456
-
角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限
-
角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限
-
权限管理:权限细化到接口,可以理解成按钮权限
-
菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单
-
菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单
-
部门管理:可配置系统组织架构,树形表格展示
-
部门管理:可配置系统组织架构,树形表格展示
-
岗位管理:配置各个部门的职位
-
岗位管理:配置各个部门的职位
...
@@ -44,16 +43,19 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
...
@@ -44,16 +43,19 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
-
支付宝支付:整合了支付宝支付并且提供了测试账号,可自行测试
-
支付宝支付:整合了支付宝支付并且提供了测试账号,可自行测试
#### 项目结构
#### 项目结构
项目采用分模块开发方式,将通用的配置放在公共模块,
```system```
模块为系统核心模块也是项目入口模块,
```logging```
模块为系统的日志模块,
```tools```
为第三方工具模块,包含了图床、邮件、七牛云、支付宝,
```generator```
为系统的代码生成模块
项目采用按功能分模块开发方式,将通用的配置放在公共模块,
```system```
模块为系统核心模块也是项目入口模块,
```logging```
模块为系统的日志模块,
```tools```
为第三方工具模块,包含了图床、邮件、七牛云、支付宝,
```generator```
为系统的代码生成模块
-
eladmin-common 公共模块
-
eladmin-common 公共模块
-
exception 项目统一异常的处理
-
annotation 为系统自定义注解
-
mapper mapstruct的通用mapper
-
aspect 自定义注解的切面
-
redis redis缓存相关配置
-
base 提供了Entity、DTO基类和mapstruct的通用mapper
-
swagger2 接口文档配置
-
config 自定义权限实现、redis配置、swagger配置
-
utils 系统通用工具类
-
exception 项目统一异常的处理
-
utils 系统通用工具类
-
eladmin-system 系统核心模块(系统启动入口)
-
eladmin-system 系统核心模块(系统启动入口)
-
config 配置跨域与静态资源,与数据权限
-
config 配置跨域与静态资源,与数据权限
-
modules 系统相关模块(登录授权、定时任务等)
-
thread 线程池相关
-
modules 系统相关模块(登录授权、系统监控、定时任务等)
-
eladmin-logging 系统日志模块
-
eladmin-logging 系统日志模块
-
eladmin-tools 系统第三方工具模块
-
eladmin-tools 系统第三方工具模块
-
eladmin-generator 系统代码生成模块
-
eladmin-generator 系统代码生成模块
...
@@ -78,6 +80,6 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
...
@@ -78,6 +80,6 @@ eladmin基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前
</table>
</table>
#### 项目捐赠
#### 项目捐赠
项目的发展离不开你的支持,请作者喝杯咖啡吧 ☕!
[
Donate
](
https://docs.auauz.net/#/jz
)
项目的发展离不开你的支持,请作者喝杯咖啡吧
!ps:辣条也行
☕!
[
Donate
](
https://docs.auauz.net/#/jz
)
#### 反馈交流
#### 反馈交流
-
QQ交流群:891137268
-
QQ交流群:891137268
eladmin-common/pom.xml
View file @
fd9fb2a6
...
@@ -5,11 +5,10 @@
...
@@ -5,11 +5,10 @@
<parent>
<parent>
<artifactId>
eladmin
</artifactId>
<artifactId>
eladmin
</artifactId>
<groupId>
me.zhengjie
</groupId>
<groupId>
me.zhengjie
</groupId>
<version>
2.
2
</version>
<version>
2.
3
</version>
</parent>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
eladmin-common
</artifactId>
<artifactId>
eladmin-common
</artifactId>
<name>
公共模块
</name>
<name>
公共模块
</name>
</project>
</project>
\ No newline at end of file
eladmin-common/src/main/java/me/zhengjie/annotation/AnonymousAccess.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.annotation
;
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
AnonymousAccess
{
}
eladmin-common/src/main/java/me/zhengjie/annotation/Query.java
View file @
fd9fb2a6
...
@@ -13,45 +13,42 @@ import java.lang.annotation.Target;
...
@@ -13,45 +13,42 @@ import java.lang.annotation.Target;
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
Query
{
public
@interface
Query
{
/
**
Dong ZhaoYang 2017/8/7 基本对象的属性名
*/
/
/
Dong ZhaoYang 2017/8/7 基本对象的属性名
String
propName
()
default
""
;
String
propName
()
default
""
;
/
**
Dong ZhaoYang 2017/8/7 查询方式
*/
/
/
Dong ZhaoYang 2017/8/7 查询方式
Type
type
()
default
Type
.
EQUAL
;
Type
type
()
default
Type
.
EQUAL
;
/**
/**
* 连接查询的属性名,如User类中的dept
* 连接查询的属性名,如User类中的dept
* @return
*/
*/
String
joinName
()
default
""
;
String
joinName
()
default
""
;
/**
/**
* 默认左连接
* 默认左连接
* @return
*/
*/
Join
join
()
default
Join
.
LEFT
;
Join
join
()
default
Join
.
LEFT
;
/**
/**
* 多字段模糊搜索,仅支持String类型字段,多个用逗号隔开, 如@Query(blurry = "email,username")
* 多字段模糊搜索,仅支持String类型字段,多个用逗号隔开, 如@Query(blurry = "email,username")
* @return
*/
*/
String
blurry
()
default
""
;
String
blurry
()
default
""
;
enum
Type
{
enum
Type
{
/
**
jie 2019/6/4 相等
*/
/
/
jie 2019/6/4 相等
EQUAL
EQUAL
/
**
Dong ZhaoYang 2017/8/7 大于等于
*/
/
/
Dong ZhaoYang 2017/8/7 大于等于
,
GREATER_THAN
,
GREATER_THAN
/
**
Dong ZhaoYang 2017/8/7 小于等于
*/
/
/
Dong ZhaoYang 2017/8/7 小于等于
,
LESS_THAN
,
LESS_THAN
/
**
Dong ZhaoYang 2017/8/7 中模糊查询
*/
/
/
Dong ZhaoYang 2017/8/7 中模糊查询
,
INNER_LIKE
,
INNER_LIKE
/
**
Dong ZhaoYang 2017/8/7 左模糊查询
*/
/
/
Dong ZhaoYang 2017/8/7 左模糊查询
,
LEFT_LIKE
,
LEFT_LIKE
/
**
Dong ZhaoYang 2017/8/7 右模糊查询
*/
/
/
Dong ZhaoYang 2017/8/7 右模糊查询
,
RIGHT_LIKE
,
RIGHT_LIKE
/
**
Dong ZhaoYang 2017/8/7 小于
*/
/
/
Dong ZhaoYang 2017/8/7 小于
,
LESS_THAN_NQ
,
LESS_THAN_NQ
//
**
jie 2019/6/4 包含
*/
// jie 2019/6/4 包含
,
IN
,
IN
}
}
...
...
eladmin-common/src/main/java/me/zhengjie/aspect/LimitAspect.java
View file @
fd9fb2a6
...
@@ -12,7 +12,6 @@ import org.aspectj.lang.annotation.Pointcut;
...
@@ -12,7 +12,6 @@ import org.aspectj.lang.annotation.Pointcut;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.script.DefaultRedisScript
;
import
org.springframework.data.redis.core.script.DefaultRedisScript
;
import
org.springframework.data.redis.core.script.RedisScript
;
import
org.springframework.data.redis.core.script.RedisScript
;
...
@@ -23,10 +22,13 @@ import java.lang.reflect.Method;
...
@@ -23,10 +22,13 @@ import java.lang.reflect.Method;
@Aspect
@Aspect
@Component
@Component
public
class
LimitAspect
{
public
class
LimitAspect
{
@Autowired
private
RedisTemplate
redisTemplate
;
private
final
RedisTemplate
<
Object
,
Object
>
redisTemplate
;
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LimitAspect
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LimitAspect
.
class
);
public
LimitAspect
(
RedisTemplate
<
Object
,
Object
>
redisTemplate
)
{
this
.
redisTemplate
=
redisTemplate
;
}
@Pointcut
(
"@annotation(me.zhengjie.annotation.Limit)"
)
@Pointcut
(
"@annotation(me.zhengjie.annotation.Limit)"
)
public
void
pointcut
()
{
public
void
pointcut
()
{
...
@@ -41,20 +43,18 @@ public class LimitAspect {
...
@@ -41,20 +43,18 @@ public class LimitAspect {
LimitType
limitType
=
limit
.
limitType
();
LimitType
limitType
=
limit
.
limitType
();
String
key
=
limit
.
key
();
String
key
=
limit
.
key
();
if
(
StringUtils
.
isEmpty
(
key
))
{
if
(
StringUtils
.
isEmpty
(
key
))
{
switch
(
limitType
)
{
if
(
limitType
==
LimitType
.
IP
)
{
case
IP:
key
=
StringUtils
.
getIp
(
request
);
key
=
StringUtils
.
getIP
(
request
);
}
else
{
break
;
key
=
signatureMethod
.
getName
();
default
:
key
=
signatureMethod
.
getName
();
}
}
}
}
ImmutableList
keys
=
ImmutableList
.
of
(
StringUtils
.
join
(
limit
.
prefix
(),
"_"
,
key
,
"_"
,
request
.
getRequestURI
().
replaceAll
(
"/"
,
"_"
)));
ImmutableList
<
Object
>
keys
=
ImmutableList
.
of
(
StringUtils
.
join
(
limit
.
prefix
(),
"_"
,
key
,
"_"
,
request
.
getRequestURI
().
replaceAll
(
"/"
,
"_"
)));
String
luaScript
=
buildLuaScript
();
String
luaScript
=
buildLuaScript
();
RedisScript
<
Number
>
redisScript
=
new
DefaultRedisScript
<>(
luaScript
,
Number
.
class
);
RedisScript
<
Number
>
redisScript
=
new
DefaultRedisScript
<>(
luaScript
,
Number
.
class
);
Number
count
=
(
Number
)
redisTemplate
.
execute
(
redisScript
,
keys
,
limit
.
count
(),
limit
.
period
());
Number
count
=
redisTemplate
.
execute
(
redisScript
,
keys
,
limit
.
count
(),
limit
.
period
());
if
(
null
!=
count
&&
count
.
intValue
()
<=
limit
.
count
())
{
if
(
null
!=
count
&&
count
.
intValue
()
<=
limit
.
count
())
{
logger
.
info
(
"第{}次访问key为 {},描述为 [{}] 的接口"
,
count
,
keys
,
limit
.
name
());
logger
.
info
(
"第{}次访问key为 {},描述为 [{}] 的接口"
,
count
,
keys
,
limit
.
name
());
return
joinPoint
.
proceed
();
return
joinPoint
.
proceed
();
...
...
eladmin-common/src/main/java/me/zhengjie/aspect/LimitType.java
View file @
fd9fb2a6
package
me.zhengjie.aspect
;
package
me.zhengjie.aspect
;
/**
* 限流枚举
* @author /
*/
public
enum
LimitType
{
public
enum
LimitType
{
// 默认
CUSTOMER
,
CUSTOMER
,
//
by ip addr
//
by ip addr
IP
;
IP
;
}
}
eladmin-common/src/main/java/me/zhengjie/base/BaseDTO.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.base
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.io.Serializable
;
import
java.sql.Timestamp
;
/**
* @author Zheng Jie
* @Date 2019年10月24日20:48:53
*/
@Getter
@Setter
public
class
BaseDTO
implements
Serializable
{
private
Boolean
isDelete
;
private
Timestamp
createTime
;
private
Timestamp
updateTime
;
}
eladmin-common/src/main/java/me/zhengjie/base/BaseEntity.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.base
;
import
lombok.*
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.hibernate.annotations.CreationTimestamp
;
import
org.hibernate.annotations.UpdateTimestamp
;
import
javax.persistence.Column
;
import
javax.persistence.MappedSuperclass
;
import
java.io.Serializable
;
import
java.sql.Timestamp
;
import
java.lang.reflect.Field
;
/**
* @author Zheng Jie
* @Date 2019年10月24日20:46:32
*/
@Getter
@Setter
@MappedSuperclass
public
class
BaseEntity
implements
Serializable
{
// 删除标识
@Column
(
name
=
"is_delete"
,
columnDefinition
=
"bit default 0"
)
private
Boolean
isDelete
=
false
;
@Column
(
name
=
"create_time"
)
@CreationTimestamp
private
Timestamp
createTime
;
@Column
(
name
=
"update_time"
)
@UpdateTimestamp
private
Timestamp
updateTime
;
public
@interface
Update
{}
@Override
public
String
toString
()
{
ToStringBuilder
builder
=
new
ToStringBuilder
(
this
);
Field
[]
fields
=
this
.
getClass
().
getDeclaredFields
();
try
{
for
(
Field
f
:
fields
)
{
f
.
setAccessible
(
true
);
builder
.
append
(
f
.
getName
(),
f
.
get
(
this
)).
append
(
"\n"
);
}
}
catch
(
Exception
e
)
{
builder
.
append
(
"toString builder encounter an error"
);
}
return
builder
.
toString
();
}
}
eladmin-common/src/main/java/me/zhengjie/
mapper/Entity
Mapper.java
→
eladmin-common/src/main/java/me/zhengjie/
base/Base
Mapper.java
View file @
fd9fb2a6
package
me.zhengjie.
mapper
;
package
me.zhengjie.
base
;
import
java.util.List
;
import
java.util.List
;
...
@@ -6,33 +6,25 @@ import java.util.List;
...
@@ -6,33 +6,25 @@ import java.util.List;
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-11-23
* @date 2018-11-23
*/
*/
public
interface
Entity
Mapper
<
D
,
E
>
{
public
interface
Base
Mapper
<
D
,
E
>
{
/**
/**
* DTO转Entity
* DTO转Entity
* @param dto
* @return
*/
*/
E
toEntity
(
D
dto
);
E
toEntity
(
D
dto
);
/**
/**
* Entity转DTO
* Entity转DTO
* @param entity
* @return
*/
*/
D
toDto
(
E
entity
);
D
toDto
(
E
entity
);
/**
/**
* DTO集合转Entity集合
* DTO集合转Entity集合
* @param dtoList
* @return
*/
*/
List
<
E
>
toEntity
(
List
<
D
>
dtoList
);
List
<
E
>
toEntity
(
List
<
D
>
dtoList
);
/**
/**
* Entity集合转DTO集合
* Entity集合转DTO集合
* @param entityList
* @return
*/
*/
List
<
D
>
toDto
(
List
<
E
>
entityList
);
List
<
D
>
toDto
(
List
<
E
>
entityList
);
}
}
eladmin-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.config
;
import
me.zhengjie.utils.SecurityUtils
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.stereotype.Service
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.stream.Collectors
;
@Service
(
value
=
"el"
)
public
class
ElPermissionConfig
{
public
Boolean
check
(
String
...
permissions
){
// 如果是匿名访问的,就放行
String
anonymous
=
"anonymous"
;
if
(
Arrays
.
asList
(
permissions
).
contains
(
anonymous
)){
return
true
;
}
// 获取当前用户的所有权限
List
<
String
>
elPermissions
=
SecurityUtils
.
getUserDetails
().
getAuthorities
().
stream
().
map
(
GrantedAuthority:
:
getAuthority
).
collect
(
Collectors
.
toList
());
// 判断当前用户的所有权限是否包含接口上定义的权限
List
<
String
>
list
=
Arrays
.
stream
(
permissions
).
filter
(
elPermissions:
:
contains
).
collect
(
Collectors
.
toList
());
return
elPermissions
.
contains
(
"admin"
)
||
list
.
size
()
!=
0
;
}
}
eladmin-common/src/main/java/me/zhengjie/
redis
/RedisConfig.java
→
eladmin-common/src/main/java/me/zhengjie/
config
/RedisConfig.java
View file @
fd9fb2a6
package
me.zhengjie.
redis
;
package
me.zhengjie.
config
;
import
cn.hutool.core.lang.Assert
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.parser.ParserConfig
;
import
com.alibaba.fastjson.parser.ParserConfig
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
me.zhengjie.utils.StringUtils
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.data.redis.RedisProperties
;
import
org.springframework.boot.autoconfigure.data.redis.RedisProperties
;
...
@@ -19,7 +23,12 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
...
@@ -19,7 +23,12 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import
org.springframework.data.redis.core.RedisOperations
;
import
org.springframework.data.redis.core.RedisOperations
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.serializer.RedisSerializationContext
;
import
org.springframework.data.redis.serializer.RedisSerializationContext
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.time.Duration
;
import
java.time.Duration
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
...
@@ -28,21 +37,19 @@ import java.time.Duration;
...
@@ -28,21 +37,19 @@ import java.time.Duration;
@Slf4j
@Slf4j
@Configuration
@Configuration
@EnableCaching
@EnableCaching
// 自动配置
@ConditionalOnClass
(
RedisOperations
.
class
)
@ConditionalOnClass
(
RedisOperations
.
class
)
@EnableConfigurationProperties
(
RedisProperties
.
class
)
@EnableConfigurationProperties
(
RedisProperties
.
class
)
public
class
RedisConfig
extends
CachingConfigurerSupport
{
public
class
RedisConfig
extends
CachingConfigurerSupport
{
/**
/**
* 设置 redis 数据默认过期时间,默认
1天
* 设置 redis 数据默认过期时间,默认
6小时
* 设置@cacheable 序列化方式
* 设置@cacheable 序列化方式
* @return
*/
*/
@Bean
@Bean
public
RedisCacheConfiguration
redisCacheConfiguration
(){
public
RedisCacheConfiguration
redisCacheConfiguration
(){
FastJsonRedisSerializer
<
Object
>
fastJsonRedisSerializer
=
new
FastJsonRedisSerializer
<>(
Object
.
class
);
FastJsonRedisSerializer
<
Object
>
fastJsonRedisSerializer
=
new
FastJsonRedisSerializer
<>(
Object
.
class
);
RedisCacheConfiguration
configuration
=
RedisCacheConfiguration
.
defaultCacheConfig
();
RedisCacheConfiguration
configuration
=
RedisCacheConfiguration
.
defaultCacheConfig
();
configuration
=
configuration
.
serializeValuesWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
fastJsonRedisSerializer
)).
entryTtl
(
Duration
.
of
Day
s
(
1
));
configuration
=
configuration
.
serializeValuesWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
fastJsonRedisSerializer
)).
entryTtl
(
Duration
.
of
Hour
s
(
6
));
return
configuration
;
return
configuration
;
}
}
...
@@ -51,21 +58,20 @@ public class RedisConfig extends CachingConfigurerSupport {
...
@@ -51,21 +58,20 @@ public class RedisConfig extends CachingConfigurerSupport {
public
RedisTemplate
<
Object
,
Object
>
redisTemplate
(
RedisConnectionFactory
redisConnectionFactory
)
{
public
RedisTemplate
<
Object
,
Object
>
redisTemplate
(
RedisConnectionFactory
redisConnectionFactory
)
{
RedisTemplate
<
Object
,
Object
>
template
=
new
RedisTemplate
<>();
RedisTemplate
<
Object
,
Object
>
template
=
new
RedisTemplate
<>();
//序列化
//序列化
FastJsonRedisSerializer
fastJsonRedisSerializer
=
new
FastJsonRedisSerializer
(
Object
.
class
);
FastJsonRedisSerializer
<
Object
>
fastJsonRedisSerializer
=
new
FastJsonRedisSerializer
<>
(
Object
.
class
);
// value值的序列化采用fastJsonRedisSerializer
// value值的序列化采用fastJsonRedisSerializer
template
.
setValueSerializer
(
fastJsonRedisSerializer
);
template
.
setValueSerializer
(
fastJsonRedisSerializer
);
template
.
setHashValueSerializer
(
fastJsonRedisSerializer
);
template
.
setHashValueSerializer
(
fastJsonRedisSerializer
);
// 全局开启AutoType,这里方便开发,使用全局的方式
// 全局开启AutoType,不建议使用
ParserConfig
.
getGlobalInstance
().
setAutoTypeSupport
(
true
);
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 建议使用这种方式,小范围指定白名单
// 建议使用这种方式,小范围指定白名单
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.domain"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.modules.system.service.dto"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.service.dto");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.service.dto"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.service.dto");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.modules.system.domain"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.domain");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.modules.quartz.domain"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.quartz.domain");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.modules.monitor.domain"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.monitor.domain");
ParserConfig
.
getGlobalInstance
().
addAccept
(
"me.zhengjie.modules.security.security"
);
//
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.security.security");
// key的序列化采用StringRedisSerializer
// key的序列化采用StringRedisSerializer
template
.
setKeySerializer
(
new
StringRedisSerializer
());
template
.
setKeySerializer
(
new
StringRedisSerializer
());
template
.
setHashKeySerializer
(
new
StringRedisSerializer
());
template
.
setHashKeySerializer
(
new
StringRedisSerializer
());
...
@@ -75,20 +81,27 @@ public class RedisConfig extends CachingConfigurerSupport {
...
@@ -75,20 +81,27 @@ public class RedisConfig extends CachingConfigurerSupport {
/**
/**
* 自定义缓存key生成策略,默认将使用该策略
* 自定义缓存key生成策略,默认将使用该策略
* 使用方法 @Cacheable
* @return
*/
*/
@Bean
@Bean
@Override
@Override
public
KeyGenerator
keyGenerator
()
{
public
KeyGenerator
keyGenerator
()
{
return
(
target
,
method
,
params
)
->
{
return
(
target
,
method
,
params
)
->
{
StringBuilder
sb
=
new
StringBuilder
();
Map
<
String
,
Object
>
container
=
new
HashMap
<>();
sb
.
append
(
target
.
getClass
().
getName
());
Class
<?>
targetClassClass
=
target
.
getClass
();
sb
.
append
(
method
.
getName
());
// 类地址
for
(
Object
obj
:
params
)
{
container
.
put
(
"class"
,
targetClassClass
.
toGenericString
());
sb
.
append
(
JSON
.
toJSONString
(
obj
).
hashCode
());
// 方法名称
container
.
put
(
"methodName"
,
method
.
getName
());
// 包名称
container
.
put
(
"package"
,
targetClassClass
.
getPackage
());
// 参数列表
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
{
container
.
put
(
String
.
valueOf
(
i
),
params
[
i
]);
}
}
return
sb
.
toString
();
// 转为JSON字符串
String
jsonString
=
JSON
.
toJSONString
(
container
);
// 做SHA256 Hash计算,得到一个SHA256摘要作为Key
return
DigestUtils
.
sha256Hex
(
jsonString
);
};
};
}
}
...
@@ -97,7 +110,7 @@ public class RedisConfig extends CachingConfigurerSupport {
...
@@ -97,7 +110,7 @@ public class RedisConfig extends CachingConfigurerSupport {
public
CacheErrorHandler
errorHandler
()
{
public
CacheErrorHandler
errorHandler
()
{
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
log
.
info
(
"初始化 -> [{}]"
,
"Redis CacheErrorHandler"
);
log
.
info
(
"初始化 -> [{}]"
,
"Redis CacheErrorHandler"
);
CacheErrorHandler
cacheErrorHandler
=
new
CacheErrorHandler
()
{
return
new
CacheErrorHandler
()
{
@Override
@Override
public
void
handleCacheGetError
(
RuntimeException
e
,
Cache
cache
,
Object
key
)
{
public
void
handleCacheGetError
(
RuntimeException
e
,
Cache
cache
,
Object
key
)
{
log
.
error
(
"Redis occur handleCacheGetError:key -> [{}]"
,
key
,
e
);
log
.
error
(
"Redis occur handleCacheGetError:key -> [{}]"
,
key
,
e
);
...
@@ -118,7 +131,74 @@ public class RedisConfig extends CachingConfigurerSupport {
...
@@ -118,7 +131,74 @@ public class RedisConfig extends CachingConfigurerSupport {
log
.
error
(
"Redis occur handleCacheClearError:"
,
e
);
log
.
error
(
"Redis occur handleCacheClearError:"
,
e
);
}
}
};
};
return
cacheErrorHandler
;
}
}
}
}
/**
* Value 序列化
*
* @author /
* @param <T>
*/
class
FastJsonRedisSerializer
<
T
>
implements
RedisSerializer
<
T
>
{
private
Class
<
T
>
clazz
;
FastJsonRedisSerializer
(
Class
<
T
>
clazz
)
{
super
();
this
.
clazz
=
clazz
;
}
@Override
public
byte
[]
serialize
(
T
t
)
{
if
(
t
==
null
)
{
return
new
byte
[
0
];
}
return
JSON
.
toJSONString
(
t
,
SerializerFeature
.
WriteClassName
).
getBytes
(
StandardCharsets
.
UTF_8
);
}
@Override
public
T
deserialize
(
byte
[]
bytes
)
{
if
(
bytes
==
null
||
bytes
.
length
<=
0
)
{
return
null
;
}
String
str
=
new
String
(
bytes
,
StandardCharsets
.
UTF_8
);
return
JSON
.
parseObject
(
str
,
clazz
);
}
}
/**
* 重写序列化器
*
* @author /
*/
class
StringRedisSerializer
implements
RedisSerializer
<
Object
>
{
private
final
Charset
charset
;
StringRedisSerializer
()
{
this
(
StandardCharsets
.
UTF_8
);
}
private
StringRedisSerializer
(
Charset
charset
)
{
Assert
.
notNull
(
charset
,
"Charset must not be null!"
);
this
.
charset
=
charset
;
}
@Override
public
String
deserialize
(
byte
[]
bytes
)
{
return
(
bytes
==
null
?
null
:
new
String
(
bytes
,
charset
));
}
@Override
public
byte
[]
serialize
(
Object
object
)
{
String
string
=
JSON
.
toJSONString
(
object
);
if
(
StringUtils
.
isBlank
(
string
))
{
return
null
;
}
string
=
string
.
replace
(
"\""
,
""
);
return
string
.
getBytes
(
charset
);
}
}
eladmin-common/src/main/java/me/zhengjie/
swagger2
/SwaggerConfig.java
→
eladmin-common/src/main/java/me/zhengjie/
config
/SwaggerConfig.java
View file @
fd9fb2a6
package
me.zhengjie.
swagger2
;
package
me.zhengjie.
config
;
import
com.fasterxml.classmate.TypeResolver
;
import
com.google.common.base.Predicates
;
import
com.google.common.base.Predicates
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.Ordered
;
import
org.springframework.data.domain.Pageable
;
import
springfox.documentation.builders.ApiInfoBuilder
;
import
springfox.documentation.builders.ApiInfoBuilder
;
import
springfox.documentation.builders.ParameterBuilder
;
import
springfox.documentation.builders.ParameterBuilder
;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.schema.AlternateTypeRule
;
import
springfox.documentation.schema.AlternateTypeRuleConvention
;
import
springfox.documentation.schema.ModelRef
;
import
springfox.documentation.schema.ModelRef
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.service.Parameter
;
import
springfox.documentation.service.Parameter
;
...
@@ -15,6 +23,8 @@ import springfox.documentation.spring.web.plugins.Docket;
...
@@ -15,6 +23,8 @@ import springfox.documentation.spring.web.plugins.Docket;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
static
com
.
google
.
common
.
collect
.
Lists
.
newArrayList
;
import
static
springfox
.
documentation
.
schema
.
AlternateTypeRules
.
newRule
;
/**
/**
* api页面 /swagger-ui.html
* api页面 /swagger-ui.html
...
@@ -33,9 +43,10 @@ public class SwaggerConfig {
...
@@ -33,9 +43,10 @@ public class SwaggerConfig {
private
Boolean
enabled
;
private
Boolean
enabled
;
@Bean
@Bean
@SuppressWarnings
(
"all"
)
public
Docket
createRestApi
()
{
public
Docket
createRestApi
()
{
ParameterBuilder
ticketPar
=
new
ParameterBuilder
();
ParameterBuilder
ticketPar
=
new
ParameterBuilder
();
List
<
Parameter
>
pars
=
new
ArrayList
<
Parameter
>();
List
<
Parameter
>
pars
=
new
ArrayList
<>();
ticketPar
.
name
(
tokenHeader
).
description
(
"token"
)
ticketPar
.
name
(
tokenHeader
).
description
(
"token"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
parameterType
(
"header"
)
...
@@ -55,8 +66,43 @@ public class SwaggerConfig {
...
@@ -55,8 +66,43 @@ public class SwaggerConfig {
private
ApiInfo
apiInfo
()
{
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
return
new
ApiInfoBuilder
()
.
title
(
"eladmin 接口文档"
)
.
title
(
"eladmin 接口文档"
)
.
version
(
"2.
1
"
)
.
version
(
"2.
3
"
)
.
build
();
.
build
();
}
}
}
}
/**
* 将Pageable转换展示在swagger中
*/
@Configuration
class
SwaggerDataConfig
{
@Bean
public
AlternateTypeRuleConvention
pageableConvention
(
final
TypeResolver
resolver
)
{
return
new
AlternateTypeRuleConvention
()
{
@Override
public
int
getOrder
()
{
return
Ordered
.
HIGHEST_PRECEDENCE
;
}
@Override
public
List
<
AlternateTypeRule
>
rules
()
{
return
newArrayList
(
newRule
(
resolver
.
resolve
(
Pageable
.
class
),
resolver
.
resolve
(
Page
.
class
)));
}
};
}
@ApiModel
@Data
private
static
class
Page
{
@ApiModelProperty
(
"页码 (0..N)"
)
private
Integer
page
;
@ApiModelProperty
(
"每页显示的数目"
)
private
Integer
size
;
@ApiModelProperty
(
"以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc"
)
private
List
<
String
>
sort
;
}
}
eladmin-common/src/main/java/me/zhengjie/exception/BadRequestException.java
View file @
fd9fb2a6
...
@@ -2,7 +2,6 @@ package me.zhengjie.exception;
...
@@ -2,7 +2,6 @@ package me.zhengjie.exception;
import
lombok.Getter
;
import
lombok.Getter
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
static
org
.
springframework
.
http
.
HttpStatus
.
BAD_REQUEST
;
import
static
org
.
springframework
.
http
.
HttpStatus
.
BAD_REQUEST
;
/**
/**
...
...
eladmin-common/src/main/java/me/zhengjie/exception/EntityExistException.java
View file @
fd9fb2a6
...
@@ -2,33 +2,18 @@ package me.zhengjie.exception;
...
@@ -2,33 +2,18 @@ package me.zhengjie.exception;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.stream.IntStream
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-11-23
* @date 2018-11-23
*/
*/
public
class
EntityExistException
extends
RuntimeException
{
public
class
EntityExistException
extends
RuntimeException
{
public
EntityExistException
(
Class
clazz
,
Object
...
saveBodyParamsMap
)
{
public
EntityExistException
(
Class
clazz
,
String
field
,
String
val
)
{
super
(
EntityExistException
.
generateMessage
(
clazz
.
getSimpleName
(),
toMap
(
String
.
class
,
String
.
class
,
saveBodyParamsMap
)));
super
(
EntityExistException
.
generateMessage
(
clazz
.
getSimpleName
(),
field
,
val
));
}
private
static
String
generateMessage
(
String
entity
,
Map
<
String
,
String
>
saveBodyParams
)
{
return
StringUtils
.
capitalize
(
entity
)
+
" 已存在 "
+
saveBodyParams
;
}
}
private
static
<
K
,
V
>
Map
<
K
,
V
>
toMap
(
private
static
String
generateMessage
(
String
entity
,
String
field
,
String
val
)
{
Class
<
K
>
keyType
,
Class
<
V
>
valueType
,
Object
...
entries
)
{
return
StringUtils
.
capitalize
(
entity
)
if
(
entries
.
length
%
2
==
1
)
+
" with "
+
field
+
" "
+
val
+
" existed"
;
throw
new
IllegalArgumentException
(
"Invalid entries"
);
return
IntStream
.
range
(
0
,
entries
.
length
/
2
).
map
(
i
->
i
*
2
)
.
collect
(
HashMap:
:
new
,
(
m
,
i
)
->
m
.
put
(
keyType
.
cast
(
entries
[
i
]),
valueType
.
cast
(
entries
[
i
+
1
])),
Map:
:
putAll
);
}
}
}
}
\ No newline at end of file
eladmin-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java
View file @
fd9fb2a6
...
@@ -2,34 +2,18 @@ package me.zhengjie.exception;
...
@@ -2,34 +2,18 @@ package me.zhengjie.exception;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.stream.IntStream
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-11-23
* @date 2018-11-23
*/
*/
public
class
EntityNotFoundException
extends
RuntimeException
{
public
class
EntityNotFoundException
extends
RuntimeException
{
public
EntityNotFoundException
(
Class
clazz
,
Object
...
searchParamsMap
)
{
public
EntityNotFoundException
(
Class
clazz
,
String
field
,
String
val
)
{
super
(
EntityNotFoundException
.
generateMessage
(
clazz
.
getSimpleName
(),
toMap
(
String
.
class
,
String
.
class
,
searchParamsMap
)));
super
(
EntityNotFoundException
.
generateMessage
(
clazz
.
getSimpleName
(),
field
,
val
));
}
private
static
String
generateMessage
(
String
entity
,
Map
<
String
,
String
>
searchParams
)
{
return
StringUtils
.
capitalize
(
entity
)
+
" 不存在 "
+
searchParams
;
}
}
private
static
<
K
,
V
>
Map
<
K
,
V
>
toMap
(
private
static
String
generateMessage
(
String
entity
,
String
field
,
String
val
)
{
Class
<
K
>
keyType
,
Class
<
V
>
valueType
,
Object
...
entries
)
{
return
StringUtils
.
capitalize
(
entity
)
if
(
entries
.
length
%
2
==
1
)
+
" with "
+
field
+
" "
+
val
+
" does not exist"
;
throw
new
IllegalArgumentException
(
"Invalid entries"
);
return
IntStream
.
range
(
0
,
entries
.
length
/
2
).
map
(
i
->
i
*
2
)
.
collect
(
HashMap:
:
new
,
(
m
,
i
)
->
m
.
put
(
keyType
.
cast
(
entries
[
i
]),
valueType
.
cast
(
entries
[
i
+
1
])),
Map:
:
putAll
);
}
}
}
}
\ No newline at end of file
eladmin-common/src/main/java/me/zhengjie/exception/handler/ApiError.java
View file @
fd9fb2a6
...
@@ -12,7 +12,7 @@ import java.time.LocalDateTime;
...
@@ -12,7 +12,7 @@ import java.time.LocalDateTime;
@Data
@Data
class
ApiError
{
class
ApiError
{
private
Integer
status
;
private
Integer
status
=
400
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
timestamp
;
private
LocalDateTime
timestamp
;
private
String
message
;
private
String
message
;
...
@@ -21,10 +21,17 @@ class ApiError {
...
@@ -21,10 +21,17 @@ class ApiError {
timestamp
=
LocalDateTime
.
now
();
timestamp
=
LocalDateTime
.
now
();
}
}
public
ApiError
(
Integer
status
,
String
message
)
{
public
static
ApiError
error
(
String
message
){
this
();
ApiError
apiError
=
new
ApiError
();
this
.
status
=
status
;
apiError
.
setMessage
(
message
);
this
.
message
=
message
;
return
apiError
;
}
public
static
ApiError
error
(
Integer
status
,
String
message
){
ApiError
apiError
=
new
ApiError
();
apiError
.
setStatus
(
status
);
apiError
.
setMessage
(
message
);
return
apiError
;
}
}
}
}
...
...
eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java
View file @
fd9fb2a6
...
@@ -11,6 +11,7 @@ import org.springframework.security.access.AccessDeniedException;
...
@@ -11,6 +11,7 @@ import org.springframework.security.access.AccessDeniedException;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
java.util.Objects
;
import
static
org
.
springframework
.
http
.
HttpStatus
.*;
import
static
org
.
springframework
.
http
.
HttpStatus
.*;
/**
/**
...
@@ -23,91 +24,73 @@ public class GlobalExceptionHandler {
...
@@ -23,91 +24,73 @@ public class GlobalExceptionHandler {
/**
/**
* 处理所有不可知的异常
* 处理所有不可知的异常
* @param e
* @return
*/
*/
@ExceptionHandler
(
Throwable
.
class
)
@ExceptionHandler
(
Throwable
.
class
)
public
ResponseEntity
handleException
(
Throwable
e
){
public
ResponseEntity
handleException
(
Throwable
e
){
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
ApiError
apiError
=
new
ApiError
(
BAD_REQUEST
.
value
(),
e
.
getMessage
());
return
buildResponseEntity
(
ApiError
.
error
(
e
.
getMessage
()));
return
buildResponseEntity
(
apiError
);
}
}
/**
/**
* 处理 接口无权访问异常AccessDeniedException
* 处理 接口无权访问异常AccessDeniedException
* @param e
* @return
*/
*/
@ExceptionHandler
(
AccessDeniedException
.
class
)
@ExceptionHandler
(
AccessDeniedException
.
class
)
public
ResponseEntity
handleAccessDeniedException
(
AccessDeniedException
e
){
public
ResponseEntity
handleAccessDeniedException
(
AccessDeniedException
e
){
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
ApiError
apiError
=
new
ApiError
(
FORBIDDEN
.
value
(),
e
.
getMessage
());
return
buildResponseEntity
(
ApiError
.
error
(
FORBIDDEN
.
value
(),
e
.
getMessage
()));
return
buildResponseEntity
(
apiError
);
}
}
/**
/**
* 处理自定义异常
* 处理自定义异常
* @param e
* @return
*/
*/
@ExceptionHandler
(
value
=
BadRequestException
.
class
)
@ExceptionHandler
(
value
=
BadRequestException
.
class
)
public
ResponseEntity
<
ApiError
>
badRequestException
(
BadRequestException
e
)
{
public
ResponseEntity
<
ApiError
>
badRequestException
(
BadRequestException
e
)
{
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
ApiError
apiError
=
new
ApiError
(
e
.
getStatus
(),
e
.
getMessage
());
return
buildResponseEntity
(
ApiError
.
error
(
e
.
getStatus
(),
e
.
getMessage
()));
return
buildResponseEntity
(
apiError
);
}
}
/**
/**
* 处理 EntityExist
* 处理 EntityExist
* @param e
* @return
*/
*/
@ExceptionHandler
(
value
=
EntityExistException
.
class
)
@ExceptionHandler
(
value
=
EntityExistException
.
class
)
public
ResponseEntity
<
ApiError
>
entityExistException
(
EntityExistException
e
)
{
public
ResponseEntity
<
ApiError
>
entityExistException
(
EntityExistException
e
)
{
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
ApiError
apiError
=
new
ApiError
(
BAD_REQUEST
.
value
(),
e
.
getMessage
());
return
buildResponseEntity
(
ApiError
.
error
(
e
.
getMessage
()));
return
buildResponseEntity
(
apiError
);
}
}
/**
/**
* 处理 EntityNotFound
* 处理 EntityNotFound
* @param e
* @return
*/
*/
@ExceptionHandler
(
value
=
EntityNotFoundException
.
class
)
@ExceptionHandler
(
value
=
EntityNotFoundException
.
class
)
public
ResponseEntity
<
ApiError
>
entityNotFoundException
(
EntityNotFoundException
e
)
{
public
ResponseEntity
<
ApiError
>
entityNotFoundException
(
EntityNotFoundException
e
)
{
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
ApiError
apiError
=
new
ApiError
(
NOT_FOUND
.
value
(),
e
.
getMessage
());
return
buildResponseEntity
(
ApiError
.
error
(
NOT_FOUND
.
value
(),
e
.
getMessage
()));
return
buildResponseEntity
(
apiError
);
}
}
/**
/**
* 处理所有接口数据验证异常
* 处理所有接口数据验证异常
* @param e
* @returns
*/
*/
@ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
@ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
public
ResponseEntity
<
ApiError
>
handleMethodArgumentNotValidException
(
MethodArgumentNotValidException
e
){
public
ResponseEntity
<
ApiError
>
handleMethodArgumentNotValidException
(
MethodArgumentNotValidException
e
){
// 打印堆栈信息
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
String
[]
str
=
e
.
getBindingResult
().
getAllErrors
().
get
(
0
).
getCodes
()[
1
].
split
(
"\\."
);
String
[]
str
=
Objects
.
requireNonNull
(
e
.
getBindingResult
().
getAllErrors
().
get
(
0
).
getCodes
())[
1
].
split
(
"\\."
);
StringBuffer
msg
=
new
StringBuffer
(
str
[
1
]+
":"
);
String
message
=
e
.
getBindingResult
().
getAllErrors
().
get
(
0
).
getDefaultMessage
();
msg
.
append
(
e
.
getBindingResult
().
getAllErrors
().
get
(
0
).
getDefaultMessage
());
if
(
"不能为空"
.
equals
(
message
)){
ApiError
apiError
=
new
ApiError
(
BAD_REQUEST
.
value
(),
msg
.
toString
());
message
=
str
[
1
]
+
":"
+
message
;
return
buildResponseEntity
(
apiError
);
}
return
buildResponseEntity
(
ApiError
.
error
(
message
));
}
}
/**
/**
* 统一返回
* 统一返回
* @param apiError
* @return
*/
*/
private
ResponseEntity
<
ApiError
>
buildResponseEntity
(
ApiError
apiError
)
{
private
ResponseEntity
<
ApiError
>
buildResponseEntity
(
ApiError
apiError
)
{
return
new
ResponseEntity
(
apiError
,
HttpStatus
.
valueOf
(
apiError
.
getStatus
()));
return
new
ResponseEntity
<>
(
apiError
,
HttpStatus
.
valueOf
(
apiError
.
getStatus
()));
}
}
}
}
eladmin-common/src/main/java/me/zhengjie/redis/FastJsonRedisSerializer.java
deleted
100644 → 0
View file @
7895e547
package
me.zhengjie.redis
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
org.springframework.data.redis.serializer.SerializationException
;
import
java.nio.charset.Charset
;
/**
* Value 序列化
*
* @author /
* @param <T>
*/
public
class
FastJsonRedisSerializer
<
T
>
implements
RedisSerializer
<
T
>
{
public
static
final
Charset
DEFAULT_CHARSET
=
Charset
.
forName
(
"UTF-8"
);
private
Class
<
T
>
clazz
;
public
FastJsonRedisSerializer
(
Class
<
T
>
clazz
)
{
super
();
this
.
clazz
=
clazz
;
}
@Override
public
byte
[]
serialize
(
T
t
)
throws
SerializationException
{
if
(
t
==
null
)
{
return
new
byte
[
0
];
}
return
JSON
.
toJSONString
(
t
,
SerializerFeature
.
WriteClassName
).
getBytes
(
DEFAULT_CHARSET
);
}
@Override
public
T
deserialize
(
byte
[]
bytes
)
throws
SerializationException
{
if
(
bytes
==
null
||
bytes
.
length
<=
0
)
{
return
null
;
}
String
str
=
new
String
(
bytes
,
DEFAULT_CHARSET
);
return
(
T
)
JSON
.
parseObject
(
str
,
clazz
);
}
}
eladmin-common/src/main/java/me/zhengjie/redis/StringRedisSerializer.java
deleted
100644 → 0
View file @
7895e547
package
me.zhengjie.redis
;
import
cn.hutool.core.lang.Assert
;
import
com.alibaba.fastjson.JSON
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
java.nio.charset.Charset
;
/**
* 重写序列化器
*
* @author /
*/
public
class
StringRedisSerializer
implements
RedisSerializer
<
Object
>
{
private
final
Charset
charset
;
private
final
String
target
=
"\""
;
private
final
String
replacement
=
""
;
public
StringRedisSerializer
()
{
this
(
Charset
.
forName
(
"UTF8"
));
}
public
StringRedisSerializer
(
Charset
charset
)
{
Assert
.
notNull
(
charset
,
"Charset must not be null!"
);
this
.
charset
=
charset
;
}
@Override
public
String
deserialize
(
byte
[]
bytes
)
{
return
(
bytes
==
null
?
null
:
new
String
(
bytes
,
charset
));
}
@Override
public
byte
[]
serialize
(
Object
object
)
{
String
string
=
JSON
.
toJSONString
(
object
);
if
(
string
==
null
)
{
return
null
;
}
string
=
string
.
replace
(
target
,
replacement
);
return
string
.
getBytes
(
charset
);
}
}
\ No newline at end of file
eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerDataConfig.java
deleted
100644 → 0
View file @
7895e547
package
me.zhengjie.swagger2
;
import
com.fasterxml.classmate.TypeResolver
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.Ordered
;
import
org.springframework.data.domain.Pageable
;
import
springfox.documentation.schema.AlternateTypeRule
;
import
springfox.documentation.schema.AlternateTypeRuleConvention
;
import
java.util.List
;
import
static
com
.
google
.
common
.
collect
.
Lists
.
newArrayList
;
import
static
springfox
.
documentation
.
schema
.
AlternateTypeRules
.
newRule
;
/** * 将Pageable转换展示在swagger中 */
@Configuration
public
class
SwaggerDataConfig
{
@Bean
public
AlternateTypeRuleConvention
pageableConvention
(
final
TypeResolver
resolver
)
{
return
new
AlternateTypeRuleConvention
()
{
@Override
public
int
getOrder
()
{
return
Ordered
.
HIGHEST_PRECEDENCE
;
}
@Override
public
List
<
AlternateTypeRule
>
rules
()
{
return
newArrayList
(
newRule
(
resolver
.
resolve
(
Pageable
.
class
),
resolver
.
resolve
(
Page
.
class
)));
}
};
}
@ApiModel
static
class
Page
{
@ApiModelProperty
(
"页码 (0..N)"
)
private
Integer
page
;
@ApiModelProperty
(
"每页显示的数目"
)
private
Integer
size
;
@ApiModelProperty
(
"以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc"
)
private
List
<
String
>
sort
;
public
Integer
getPage
()
{
return
page
;
}
public
void
setPage
(
Integer
page
)
{
this
.
page
=
page
;
}
public
Integer
getSize
()
{
return
size
;
}
public
void
setSize
(
Integer
size
)
{
this
.
size
=
size
;
}
public
List
<
String
>
getSort
()
{
return
sort
;
}
public
void
setSort
(
List
<
String
>
sort
)
{
this
.
sort
=
sort
;
}
}
}
\ No newline at end of file
Prev
1
2
3
4
5
…
12
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment