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
RuoYi Vue
Commits
46444bd0
Commit
46444bd0
authored
Oct 08, 2019
by
RuoYi
Browse files
RuoYi-Vue 1.0
parent
5bc74554
Changes
400
Hide whitespace changes
Inline
Side-by-side
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
com.ruoyi.framework.aspectj.lang.enums.DataSourceType
;
/**
* 自定义多数据源切换注解
*
* @author ruoyi
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Inherited
public
@interface
DataSource
{
/**
* 切换数据源名称
*/
public
DataSourceType
value
()
default
DataSourceType
.
MASTER
;
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
com.ruoyi.framework.aspectj.lang.enums.BusinessType
;
import
com.ruoyi.framework.aspectj.lang.enums.OperatorType
;
/**
* 自定义操作日志记录注解
*
* @author ruoyi
*
*/
@Target
({
ElementType
.
PARAMETER
,
ElementType
.
METHOD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
Log
{
/**
* 模块
*/
public
String
title
()
default
""
;
/**
* 功能
*/
public
BusinessType
businessType
()
default
BusinessType
.
OTHER
;
/**
* 操作人类别
*/
public
OperatorType
operatorType
()
default
OperatorType
.
MANAGE
;
/**
* 是否保存请求的参数
*/
public
boolean
isSaveRequestData
()
default
true
;
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.enums
;
/**
* 操作状态
*
* @author ruoyi
*
*/
public
enum
BusinessStatus
{
/**
* 成功
*/
SUCCESS
,
/**
* 失败
*/
FAIL
,
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.enums
;
/**
* 业务操作类型
*
* @author ruoyi
*/
public
enum
BusinessType
{
/**
* 其它
*/
OTHER
,
/**
* 新增
*/
INSERT
,
/**
* 修改
*/
UPDATE
,
/**
* 删除
*/
DELETE
,
/**
* 授权
*/
GRANT
,
/**
* 导出
*/
EXPORT
,
/**
* 导入
*/
IMPORT
,
/**
* 强退
*/
FORCE
,
/**
* 生成代码
*/
GENCODE
,
/**
* 清空数据
*/
CLEAN
,
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.enums
;
/**
* 数据源
*
* @author ruoyi
*/
public
enum
DataSourceType
{
/**
* 主库
*/
MASTER
,
/**
* 从库
*/
SLAVE
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.aspectj.lang.enums
;
/**
* 操作人类别
*
* @author ruoyi
*/
public
enum
OperatorType
{
/**
* 其它
*/
OTHER
,
/**
* 后台用户
*/
MANAGE
,
/**
* 手机端用户
*/
MOBILE
}
ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
/**
* 程序注解配置
*
* @author ruoyi
*/
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy
(
exposeProxy
=
true
)
// 指定要扫描的Mapper类的包的路径
@MapperScan
(
"com.ruoyi.project.**.mapper"
)
public
class
ApplicationConfig
{
}
ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.sql.DataSource
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Primary
;
import
com.alibaba.druid.pool.DruidDataSource
;
import
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder
;
import
com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties
;
import
com.alibaba.druid.util.Utils
;
import
com.ruoyi.framework.aspectj.lang.enums.DataSourceType
;
import
com.ruoyi.framework.config.properties.DruidProperties
;
import
com.ruoyi.framework.datasource.DynamicDataSource
;
/**
* druid 配置多数据源
*
* @author ruoyi
*/
@Configuration
public
class
DruidConfig
{
@Bean
@ConfigurationProperties
(
"spring.datasource.druid.master"
)
public
DataSource
masterDataSource
(
DruidProperties
druidProperties
)
{
DruidDataSource
dataSource
=
DruidDataSourceBuilder
.
create
().
build
();
return
druidProperties
.
dataSource
(
dataSource
);
}
@Bean
@ConfigurationProperties
(
"spring.datasource.druid.slave"
)
@ConditionalOnProperty
(
prefix
=
"spring.datasource.druid.slave"
,
name
=
"enabled"
,
havingValue
=
"true"
)
public
DataSource
slaveDataSource
(
DruidProperties
druidProperties
)
{
DruidDataSource
dataSource
=
DruidDataSourceBuilder
.
create
().
build
();
return
druidProperties
.
dataSource
(
dataSource
);
}
@Bean
(
name
=
"dynamicDataSource"
)
@Primary
public
DynamicDataSource
dataSource
(
DataSource
masterDataSource
,
DataSource
slaveDataSource
)
{
Map
<
Object
,
Object
>
targetDataSources
=
new
HashMap
<>();
targetDataSources
.
put
(
DataSourceType
.
MASTER
.
name
(),
masterDataSource
);
targetDataSources
.
put
(
DataSourceType
.
SLAVE
.
name
(),
slaveDataSource
);
return
new
DynamicDataSource
(
masterDataSource
,
targetDataSources
);
}
/**
* 去除监控页面底部的广告
*/
@SuppressWarnings
({
"rawtypes"
,
"unchecked"
})
@Bean
@ConditionalOnProperty
(
name
=
"spring.datasource.druid.statViewServlet.enabled"
,
havingValue
=
"true"
)
public
FilterRegistrationBean
removeDruidFilterRegistrationBean
(
DruidStatProperties
properties
)
{
// 获取web监控页面的参数
DruidStatProperties
.
StatViewServlet
config
=
properties
.
getStatViewServlet
();
// 提取common.js的配置路径
String
pattern
=
config
.
getUrlPattern
()
!=
null
?
config
.
getUrlPattern
()
:
"/druid/*"
;
String
commonJsPattern
=
pattern
.
replaceAll
(
"\\*"
,
"js/common.js"
);
final
String
filePath
=
"support/http/resources/js/common.js"
;
// 创建filter进行过滤
Filter
filter
=
new
Filter
()
{
@Override
public
void
init
(
javax
.
servlet
.
FilterConfig
filterConfig
)
throws
ServletException
{
}
@Override
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
chain
.
doFilter
(
request
,
response
);
// 重置缓冲区,响应头不会被重置
response
.
resetBuffer
();
// 获取common.js
String
text
=
Utils
.
readFromResource
(
filePath
);
// 正则替换banner, 除去底部的广告信息
text
=
text
.
replaceAll
(
"<a.*?banner\"></a><br/>"
,
""
);
text
=
text
.
replaceAll
(
"powered.*?shrek.wang</a>"
,
""
);
response
.
getWriter
().
write
(
text
);
}
@Override
public
void
destroy
()
{
}
};
FilterRegistrationBean
registrationBean
=
new
FilterRegistrationBean
();
registrationBean
.
setFilter
(
filter
);
registrationBean
.
addUrlPatterns
(
commonJsPattern
);
return
registrationBean
;
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.fasterxml.jackson.databind.JavaType
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.type.TypeFactory
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
org.springframework.data.redis.serializer.SerializationException
;
import
com.alibaba.fastjson.parser.ParserConfig
;
import
org.springframework.util.Assert
;
import
java.nio.charset.Charset
;
/**
* Redis使用FastJson序列化
*
* @author ruoyi
*/
public
class
FastJson2JsonRedisSerializer
<
T
>
implements
RedisSerializer
<
T
>
{
@SuppressWarnings
(
"unused"
)
private
ObjectMapper
objectMapper
=
new
ObjectMapper
();
public
static
final
Charset
DEFAULT_CHARSET
=
Charset
.
forName
(
"UTF-8"
);
private
Class
<
T
>
clazz
;
static
{
ParserConfig
.
getGlobalInstance
().
setAutoTypeSupport
(
true
);
}
public
FastJson2JsonRedisSerializer
(
Class
<
T
>
clazz
)
{
super
();
this
.
clazz
=
clazz
;
}
public
byte
[]
serialize
(
T
t
)
throws
SerializationException
{
if
(
t
==
null
)
{
return
new
byte
[
0
];
}
return
JSON
.
toJSONString
(
t
,
SerializerFeature
.
WriteClassName
).
getBytes
(
DEFAULT_CHARSET
);
}
public
T
deserialize
(
byte
[]
bytes
)
throws
SerializationException
{
if
(
bytes
==
null
||
bytes
.
length
<=
0
)
{
return
null
;
}
String
str
=
new
String
(
bytes
,
DEFAULT_CHARSET
);
return
JSON
.
parseObject
(
str
,
clazz
);
}
public
void
setObjectMapper
(
ObjectMapper
objectMapper
)
{
Assert
.
notNull
(
objectMapper
,
"'objectMapper' must not be null"
);
this
.
objectMapper
=
objectMapper
;
}
protected
JavaType
getJavaType
(
Class
<?>
clazz
)
{
return
TypeFactory
.
defaultInstance
().
constructType
(
clazz
);
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.servlet.DispatcherType
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.common.xss.XssFilter
;
/**
* Filter配置
*
* @author ruoyi
*/
@Configuration
public
class
FilterConfig
{
@Value
(
"${xss.enabled}"
)
private
String
enabled
;
@Value
(
"${xss.excludes}"
)
private
String
excludes
;
@Value
(
"${xss.urlPatterns}"
)
private
String
urlPatterns
;
@SuppressWarnings
({
"rawtypes"
,
"unchecked"
})
@Bean
public
FilterRegistrationBean
xssFilterRegistration
()
{
FilterRegistrationBean
registration
=
new
FilterRegistrationBean
();
registration
.
setDispatcherTypes
(
DispatcherType
.
REQUEST
);
registration
.
setFilter
(
new
XssFilter
());
registration
.
addUrlPatterns
(
StringUtils
.
split
(
urlPatterns
,
","
));
registration
.
setName
(
"xssFilter"
);
registration
.
setOrder
(
Integer
.
MAX_VALUE
);
Map
<
String
,
String
>
initParameters
=
new
HashMap
<
String
,
String
>();
initParameters
.
put
(
"excludes"
,
excludes
);
initParameters
.
put
(
"enabled"
,
enabled
);
registration
.
setInitParameters
(
initParameters
);
return
registration
;
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
javax.sql.DataSource
;
import
org.apache.ibatis.io.VFS
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.mybatis.spring.SqlSessionFactoryBean
;
import
org.mybatis.spring.boot.autoconfigure.SpringBootVFS
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.env.Environment
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.support.PathMatchingResourcePatternResolver
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
org.springframework.core.type.classreading.CachingMetadataReaderFactory
;
import
org.springframework.core.type.classreading.MetadataReader
;
import
org.springframework.core.type.classreading.MetadataReaderFactory
;
import
org.springframework.util.ClassUtils
;
/**
* Mybatis支持*匹配扫描包
*
* @author ruoyi
*/
@Configuration
public
class
MyBatisConfig
{
@Autowired
private
Environment
env
;
static
final
String
DEFAULT_RESOURCE_PATTERN
=
"**/*.class"
;
public
static
String
setTypeAliasesPackage
(
String
typeAliasesPackage
)
{
ResourcePatternResolver
resolver
=
(
ResourcePatternResolver
)
new
PathMatchingResourcePatternResolver
();
MetadataReaderFactory
metadataReaderFactory
=
new
CachingMetadataReaderFactory
(
resolver
);
List
<
String
>
allResult
=
new
ArrayList
<
String
>();
try
{
for
(
String
aliasesPackage
:
typeAliasesPackage
.
split
(
","
))
{
List
<
String
>
result
=
new
ArrayList
<
String
>();
aliasesPackage
=
ResourcePatternResolver
.
CLASSPATH_ALL_URL_PREFIX
+
ClassUtils
.
convertClassNameToResourcePath
(
aliasesPackage
.
trim
())
+
"/"
+
DEFAULT_RESOURCE_PATTERN
;
Resource
[]
resources
=
resolver
.
getResources
(
aliasesPackage
);
if
(
resources
!=
null
&&
resources
.
length
>
0
)
{
MetadataReader
metadataReader
=
null
;
for
(
Resource
resource
:
resources
)
{
if
(
resource
.
isReadable
())
{
metadataReader
=
metadataReaderFactory
.
getMetadataReader
(
resource
);
try
{
result
.
add
(
Class
.
forName
(
metadataReader
.
getClassMetadata
().
getClassName
()).
getPackage
().
getName
());
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
}
}
}
if
(
result
.
size
()
>
0
)
{
HashSet
<
String
>
hashResult
=
new
HashSet
<
String
>(
result
);
allResult
.
addAll
(
hashResult
);
}
}
if
(
allResult
.
size
()
>
0
)
{
typeAliasesPackage
=
String
.
join
(
","
,
(
String
[])
allResult
.
toArray
(
new
String
[
0
]));
}
else
{
throw
new
RuntimeException
(
"mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:"
+
typeAliasesPackage
+
"未找到任何包"
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
return
typeAliasesPackage
;
}
@Bean
public
SqlSessionFactory
sqlSessionFactory
(
DataSource
dataSource
)
throws
Exception
{
String
typeAliasesPackage
=
env
.
getProperty
(
"mybatis.typeAliasesPackage"
);
String
mapperLocations
=
env
.
getProperty
(
"mybatis.mapperLocations"
);
typeAliasesPackage
=
setTypeAliasesPackage
(
typeAliasesPackage
);
VFS
.
addImplClass
(
SpringBootVFS
.
class
);
final
SqlSessionFactoryBean
sessionFactory
=
new
SqlSessionFactoryBean
();
sessionFactory
.
setDataSource
(
dataSource
);
sessionFactory
.
setTypeAliasesPackage
(
typeAliasesPackage
);
sessionFactory
.
setMapperLocations
(
new
PathMatchingResourcePatternResolver
().
getResources
(
mapperLocations
));
return
sessionFactory
.
getObject
();
}
}
\ No newline at end of file
ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.springframework.cache.annotation.CachingConfigurerSupport
;
import
org.springframework.cache.annotation.EnableCaching
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.serializer.StringRedisSerializer
;
import
com.fasterxml.jackson.annotation.JsonAutoDetect
;
import
com.fasterxml.jackson.annotation.PropertyAccessor
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
/**
* redis配置
*
* @author ruoyi
*/
@Configuration
@EnableCaching
public
class
RedisConfig
extends
CachingConfigurerSupport
{
@Bean
@SuppressWarnings
(
value
=
{
"unchecked"
,
"rawtypes"
})
public
RedisTemplate
<
Object
,
Object
>
redisTemplate
(
RedisConnectionFactory
connectionFactory
)
{
RedisTemplate
<
Object
,
Object
>
template
=
new
RedisTemplate
<>();
template
.
setConnectionFactory
(
connectionFactory
);
FastJson2JsonRedisSerializer
serializer
=
new
FastJson2JsonRedisSerializer
(
Object
.
class
);
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
setVisibility
(
PropertyAccessor
.
ALL
,
JsonAutoDetect
.
Visibility
.
ANY
);
mapper
.
enableDefaultTyping
(
ObjectMapper
.
DefaultTyping
.
NON_FINAL
);
serializer
.
setObjectMapper
(
mapper
);
template
.
setValueSerializer
(
serializer
);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template
.
setKeySerializer
(
new
StringRedisSerializer
());
template
.
afterPropertiesSet
();
return
template
;
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
com.ruoyi.common.constant.Constants
;
/**
* 通用配置
*
* @author ruoyi
*/
@Configuration
public
class
ResourcesConfig
implements
WebMvcConfigurer
{
@Override
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
/** 本地文件上传路径 */
registry
.
addResourceHandler
(
Constants
.
RESOURCE_PREFIX
+
"/**"
).
addResourceLocations
(
"file:"
+
RuoYiConfig
.
getProfile
()
+
"/"
);
/** swagger配置 */
registry
.
addResourceHandler
(
"swagger-ui.html"
).
addResourceLocations
(
"classpath:/META-INF/resources/"
);
registry
.
addResourceHandler
(
"/webjars/**"
).
addResourceLocations
(
"classpath:/META-INF/resources/webjars/"
);
}
}
\ No newline at end of file
ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
/**
* 读取项目相关配置
*
* @author ruoyi
*/
@Component
@ConfigurationProperties
(
prefix
=
"ruoyi"
)
public
class
RuoYiConfig
{
/** 项目名称 */
private
String
name
;
/** 版本 */
private
String
version
;
/** 版权年份 */
private
String
copyrightYear
;
/** 实例演示开关 */
private
boolean
demoEnabled
;
/** 上传路径 */
private
static
String
profile
;
/** 获取地址开关 */
private
static
boolean
addressEnabled
;
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getVersion
()
{
return
version
;
}
public
void
setVersion
(
String
version
)
{
this
.
version
=
version
;
}
public
String
getCopyrightYear
()
{
return
copyrightYear
;
}
public
void
setCopyrightYear
(
String
copyrightYear
)
{
this
.
copyrightYear
=
copyrightYear
;
}
public
boolean
isDemoEnabled
()
{
return
demoEnabled
;
}
public
void
setDemoEnabled
(
boolean
demoEnabled
)
{
this
.
demoEnabled
=
demoEnabled
;
}
public
static
String
getProfile
()
{
return
profile
;
}
public
void
setProfile
(
String
profile
)
{
RuoYiConfig
.
profile
=
profile
;
}
public
static
boolean
isAddressEnabled
()
{
return
addressEnabled
;
}
public
void
setAddressEnabled
(
boolean
addressEnabled
)
{
RuoYiConfig
.
addressEnabled
=
addressEnabled
;
}
/**
* 获取头像上传路径
*/
public
static
String
getAvatarPath
()
{
return
getProfile
()
+
"/avatar"
;
}
/**
* 获取下载路径
*/
public
static
String
getDownloadPath
()
{
return
getProfile
()
+
"/download/"
;
}
/**
* 获取上传路径
*/
public
static
String
getUploadPath
()
{
return
getProfile
()
+
"/upload"
;
}
}
\ No newline at end of file
ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
import
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.config.http.SessionCreationPolicy
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter
;
import
com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl
;
import
com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl
;
/**
* spring security配置
*
* @author ruoyi
*/
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
,
securedEnabled
=
true
)
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
/**
* 自定义用户认证逻辑
*/
@Autowired
private
UserDetailsService
userDetailsService
;
/**
* 认证失败处理类
*/
@Autowired
private
AuthenticationEntryPointImpl
unauthorizedHandler
;
/**
* 退出处理类
*/
@Autowired
private
LogoutSuccessHandlerImpl
logoutSuccessHandler
;
/**
* token认证过滤器
*/
@Autowired
private
JwtAuthenticationTokenFilter
authenticationTokenFilter
;
/**
* 解决 无法直接注入 AuthenticationManager
*
* @return
* @throws Exception
*/
@Bean
@Override
public
AuthenticationManager
authenticationManagerBean
()
throws
Exception
{
return
super
.
authenticationManagerBean
();
}
/**
* anyRequest | 匹配所有请求路径
* access | SpringEl表达式结果为true时可以访问
* anonymous | 匿名可以访问
* denyAll | 用户不能访问
* fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
* hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
* hasRole | 如果有参数,参数表示角色,则其角色可以访问
* permitAll | 用户可以任意访问
* rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问
*/
@Override
protected
void
configure
(
HttpSecurity
httpSecurity
)
throws
Exception
{
httpSecurity
// CRSF禁用,因为不使用session
.
csrf
().
disable
()
// 认证失败处理类
.
exceptionHandling
().
authenticationEntryPoint
(
unauthorizedHandler
).
and
()
// 基于token,所以不需要session
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
// 过滤请求
.
authorizeRequests
()
// 对于登录login 验证码captchaImage 允许匿名访问
.
antMatchers
(
"/login"
,
"/captchaImage"
).
anonymous
()
.
antMatchers
(
HttpMethod
.
GET
,
"/*.html"
,
"/**/*.html"
,
"/**/*.css"
,
"/**/*.js"
).
permitAll
()
.
antMatchers
(
"/profile/**"
).
anonymous
()
.
antMatchers
(
"/swagger-ui.html"
).
anonymous
()
.
antMatchers
(
"/swagger-resources/**"
).
anonymous
()
.
antMatchers
(
"/webjars/**"
).
anonymous
()
.
antMatchers
(
"/*/api-docs"
).
anonymous
()
.
antMatchers
(
"/druid/**"
).
anonymous
()
// 除上面外的所有请求全部需要鉴权认证
.
anyRequest
().
authenticated
()
.
and
()
.
headers
().
frameOptions
().
disable
();
httpSecurity
.
logout
().
logoutUrl
(
"/logout"
).
logoutSuccessHandler
(
logoutSuccessHandler
);
// 添加JWT filter
httpSecurity
.
addFilterBefore
(
authenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
/**
* 强散列哈希加密实现
*/
@Bean
public
BCryptPasswordEncoder
bCryptPasswordEncoder
()
{
return
new
BCryptPasswordEncoder
();
}
/**
* 身份认证接口
*/
@Override
protected
void
configure
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
auth
.
userDetailsService
(
userDetailsService
).
passwordEncoder
(
bCryptPasswordEncoder
());
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/ServerConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.stereotype.Component
;
import
com.ruoyi.common.utils.ServletUtils
;
/**
* 服务相关配置
*
* @author ruoyi
*/
@Component
public
class
ServerConfig
{
/**
* 获取完整的请求路径,包括:域名,端口,上下文访问路径
*
* @return 服务地址
*/
public
String
getUrl
()
{
HttpServletRequest
request
=
ServletUtils
.
getRequest
();
return
getDomain
(
request
);
}
public
static
String
getDomain
(
HttpServletRequest
request
)
{
StringBuffer
url
=
request
.
getRequestURL
();
String
contextPath
=
request
.
getServletContext
().
getContextPath
();
return
url
.
delete
(
url
.
length
()
-
request
.
getRequestURI
().
length
(),
url
.
length
()).
append
(
contextPath
).
toString
();
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
io.swagger.annotations.ApiOperation
;
import
springfox.documentation.builders.ApiInfoBuilder
;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.builders.RequestHandlerSelectors
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.service.Contact
;
import
springfox.documentation.spi.DocumentationType
;
import
springfox.documentation.spring.web.plugins.Docket
;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
/**
* Swagger2的接口配置
*
* @author ruoyi
*/
@Configuration
@EnableSwagger2
public
class
SwaggerConfig
{
/** 系统基础配置 */
@Autowired
private
RuoYiConfig
ruoyiConfig
;
/**
* 创建API
*/
@Bean
public
Docket
createRestApi
()
{
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.
apiInfo
(
apiInfo
())
// 设置哪些接口暴露给Swagger展示
.
select
()
// 扫描所有有注解的api,用这种方式更灵活
.
apis
(
RequestHandlerSelectors
.
withMethodAnnotation
(
ApiOperation
.
class
))
// 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.
paths
(
PathSelectors
.
any
())
.
build
();
}
/**
* 添加摘要信息
*/
private
ApiInfo
apiInfo
()
{
// 用ApiInfoBuilder进行定制
return
new
ApiInfoBuilder
()
// 设置标题
.
title
(
"标题:余心管理系统_接口文档"
)
// 描述
.
description
(
"描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块..."
)
// 作者信息
.
contact
(
new
Contact
(
ruoyiConfig
.
getName
(),
null
,
null
))
// 版本
.
version
(
"版本号:"
+
ruoyiConfig
.
getVersion
())
.
build
();
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ScheduledThreadPoolExecutor
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
org.apache.commons.lang3.concurrent.BasicThreadFactory
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
import
com.ruoyi.common.utils.Threads
;
/**
* 线程池配置
*
* @author ruoyi
**/
@Configuration
public
class
ThreadPoolConfig
{
// 核心线程池大小
private
int
corePoolSize
=
50
;
// 最大可创建的线程数
private
int
maxPoolSize
=
200
;
// 队列最大长度
private
int
queueCapacity
=
1000
;
// 线程池维护线程所允许的空闲时间
private
int
keepAliveSeconds
=
300
;
@Bean
(
name
=
"threadPoolTaskExecutor"
)
public
ThreadPoolTaskExecutor
threadPoolTaskExecutor
()
{
ThreadPoolTaskExecutor
executor
=
new
ThreadPoolTaskExecutor
();
executor
.
setMaxPoolSize
(
maxPoolSize
);
executor
.
setCorePoolSize
(
corePoolSize
);
executor
.
setQueueCapacity
(
queueCapacity
);
executor
.
setKeepAliveSeconds
(
keepAliveSeconds
);
// 线程池对拒绝任务(无线程可用)的处理策略
executor
.
setRejectedExecutionHandler
(
new
ThreadPoolExecutor
.
CallerRunsPolicy
());
return
executor
;
}
/**
* 执行周期性或定时任务
*/
@Bean
(
name
=
"scheduledExecutorService"
)
protected
ScheduledExecutorService
scheduledExecutorService
()
{
return
new
ScheduledThreadPoolExecutor
(
corePoolSize
,
new
BasicThreadFactory
.
Builder
().
namingPattern
(
"schedule-pool-%d"
).
daemon
(
true
).
build
())
{
@Override
protected
void
afterExecute
(
Runnable
r
,
Throwable
t
)
{
super
.
afterExecute
(
r
,
t
);
Threads
.
printException
(
r
,
t
);
}
};
}
}
ruoyi/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.config.properties
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Configuration
;
import
com.alibaba.druid.pool.DruidDataSource
;
/**
* druid 配置属性
*
* @author ruoyi
*/
@Configuration
public
class
DruidProperties
{
@Value
(
"${spring.datasource.druid.initialSize}"
)
private
int
initialSize
;
@Value
(
"${spring.datasource.druid.minIdle}"
)
private
int
minIdle
;
@Value
(
"${spring.datasource.druid.maxActive}"
)
private
int
maxActive
;
@Value
(
"${spring.datasource.druid.maxWait}"
)
private
int
maxWait
;
@Value
(
"${spring.datasource.druid.timeBetweenEvictionRunsMillis}"
)
private
int
timeBetweenEvictionRunsMillis
;
@Value
(
"${spring.datasource.druid.minEvictableIdleTimeMillis}"
)
private
int
minEvictableIdleTimeMillis
;
@Value
(
"${spring.datasource.druid.maxEvictableIdleTimeMillis}"
)
private
int
maxEvictableIdleTimeMillis
;
@Value
(
"${spring.datasource.druid.validationQuery}"
)
private
String
validationQuery
;
@Value
(
"${spring.datasource.druid.testWhileIdle}"
)
private
boolean
testWhileIdle
;
@Value
(
"${spring.datasource.druid.testOnBorrow}"
)
private
boolean
testOnBorrow
;
@Value
(
"${spring.datasource.druid.testOnReturn}"
)
private
boolean
testOnReturn
;
public
DruidDataSource
dataSource
(
DruidDataSource
datasource
)
{
/** 配置初始化大小、最小、最大 */
datasource
.
setInitialSize
(
initialSize
);
datasource
.
setMaxActive
(
maxActive
);
datasource
.
setMinIdle
(
minIdle
);
/** 配置获取连接等待超时的时间 */
datasource
.
setMaxWait
(
maxWait
);
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
datasource
.
setTimeBetweenEvictionRunsMillis
(
timeBetweenEvictionRunsMillis
);
/** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
datasource
.
setMinEvictableIdleTimeMillis
(
minEvictableIdleTimeMillis
);
datasource
.
setMaxEvictableIdleTimeMillis
(
maxEvictableIdleTimeMillis
);
/**
* 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
*/
datasource
.
setValidationQuery
(
validationQuery
);
/** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
datasource
.
setTestWhileIdle
(
testWhileIdle
);
/** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource
.
setTestOnBorrow
(
testOnBorrow
);
/** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource
.
setTestOnReturn
(
testOnReturn
);
return
datasource
;
}
}
ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java
0 → 100644
View file @
46444bd0
package
com.ruoyi.framework.datasource
;
import
java.util.Map
;
import
javax.sql.DataSource
;
import
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
;
/**
* 动态数据源
*
* @author ruoyi
*/
public
class
DynamicDataSource
extends
AbstractRoutingDataSource
{
public
DynamicDataSource
(
DataSource
defaultTargetDataSource
,
Map
<
Object
,
Object
>
targetDataSources
)
{
super
.
setDefaultTargetDataSource
(
defaultTargetDataSource
);
super
.
setTargetDataSources
(
targetDataSources
);
super
.
afterPropertiesSet
();
}
@Override
protected
Object
determineCurrentLookupKey
()
{
return
DynamicDataSourceContextHolder
.
getDataSourceType
();
}
}
\ No newline at end of file
Prev
1
…
10
11
12
13
14
15
16
17
18
…
20
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