Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cloud-backend
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
framework
cloud-backend
Commits
0fa85449
Commit
0fa85449
authored
Mar 03, 2021
by
袁伟铭
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.0.0
parent
2c50a1f0
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
158 additions
and
809 deletions
+158
-809
camellia-server/pom.xml
+0
-103
camellia-server/src/main/java/com/zq/camellia/CamelliaApplication.java
+0
-28
camellia-server/src/main/java/com/zq/camellia/config/JwtAccessDeniedHandler.java
+0
-37
camellia-server/src/main/java/com/zq/camellia/config/JwtAuthenticationEntryPoint.java
+0
-39
camellia-server/src/main/java/com/zq/camellia/config/SpringSecurityConfig.java
+0
-183
camellia-server/src/main/java/com/zq/camellia/config/TokenConfigurer.java
+0
-41
camellia-server/src/main/java/com/zq/camellia/config/TokenFilter.java
+0
-105
camellia-server/src/main/java/com/zq/camellia/config/TokenProvider.java
+0
-134
camellia-server/src/main/resources/application.yml
+0
-76
camellia-server/src/main/resources/bootstrap.yml
+0
-14
cms-server/src/main/java/com/zq/cms/config/SpringSecurityConfig.java
+7
-0
common-utils/src/main/java/com/zq/common/config/limit/LimitAspect.java
+2
-2
common-utils/src/main/java/com/zq/common/utils/UploadUtils.java
+70
-2
eureka-server/pom.xml
+4
-0
eureka-server/src/main/java/com/zq/eureka/config/WebSecurityConfig.java
+18
-0
file-server/src/main/java/com/zq/file/controller/AccessController.java
+44
-0
file-server/src/main/java/com/zq/file/controller/FileController.java
+13
-44
pom.xml
+0
-1
No files found.
camellia-server/pom.xml
deleted
100644 → 0
View file @
2c50a1f0
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
cloud-backend
</artifactId>
<groupId>
com.zq
</groupId>
<version>
1.0.0
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
camellia-server
</artifactId>
<dependencies>
<dependency>
<groupId>
com.zq
</groupId>
<artifactId>
common-utils
</artifactId>
<version>
1.0.0
</version>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
</dependency>
<!--Spring boot 安全框架-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-security
</artifactId>
</dependency>
<!-- 连接配置中心 -->
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-config
</artifactId>
</dependency>
<!--Spring boot Web容器-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<!--Spring boot 测试-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
<!--Spring devtools 热部署-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-devtools
</artifactId>
<scope>
runtime
</scope>
<optional>
true
</optional>
</dependency>
<!--Spring boot Redis-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-redis
</artifactId>
</dependency>
<!--Mybatis plus-->
<dependency>
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-boot-starter
</artifactId>
<version>
${mybatis.plus.version}
</version>
</dependency>
<!-- druid数据源驱动 -->
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid-spring-boot-starter
</artifactId>
<version>
${alibaba.druid.version}
</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
<scope>
runtime
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
<dependencies>
<!-- spring热部署 -->
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency> -->
</dependencies>
</plugin>
</plugins>
<!-- 使用@profiles.active@需要添加以下内容 -->
<resources>
<resource>
<directory>
src/main/resources
</directory>
<!--开启过滤,用指定的参数替换directory下的文件中的参数-->
<filtering>
true
</filtering>
</resource>
</resources>
</build>
</project>
\ No newline at end of file
camellia-server/src/main/java/com/zq/camellia/CamelliaApplication.java
deleted
100644 → 0
View file @
2c50a1f0
package
com
.
zq
.
camellia
;
import
com.zq.common.config.base.SecurityProperties
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.cloud.client.discovery.EnableDiscoveryClient
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.scheduling.annotation.EnableScheduling
;
@EnableScheduling
@MapperScan
(
"com.zq.camellia.dao"
)
@EnableDiscoveryClient
@SpringBootApplication
(
scanBasePackages
=
{
"com.zq.camellia"
,
"com.zq.common.config"
})
public
class
CamelliaApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
CamelliaApplication
.
class
,
args
);
}
@Bean
@ConfigurationProperties
(
prefix
=
"jwt"
)
public
SecurityProperties
securityProperties
()
{
return
new
SecurityProperties
();
}
}
camellia-server/src/main/java/com/zq/camellia/config/JwtAccessDeniedHandler.java
deleted
100644 → 0
View file @
2c50a1f0
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
zq
.
camellia
.
config
;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* @author Zheng Jie
*/
@Component
public
class
JwtAccessDeniedHandler
implements
AccessDeniedHandler
{
@Override
public
void
handle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AccessDeniedException
accessDeniedException
)
throws
IOException
{
//当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应
response
.
sendError
(
HttpServletResponse
.
SC_FORBIDDEN
,
accessDeniedException
.
getMessage
());
}
}
camellia-server/src/main/java/com/zq/camellia/config/JwtAuthenticationEntryPoint.java
deleted
100644 → 0
View file @
2c50a1f0
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
zq
.
camellia
.
config
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.web.AuthenticationEntryPoint
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* @author Zheng Jie
*/
@Component
public
class
JwtAuthenticationEntryPoint
implements
AuthenticationEntryPoint
{
@Override
public
void
commence
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AuthenticationException
authException
)
throws
IOException
{
// 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
authException
==
null
?
"Unauthorized"
:
authException
.
getMessage
());
}
}
camellia-server/src/main/java/com/zq/camellia/config/SpringSecurityConfig.java
deleted
100644 → 0
View file @
2c50a1f0
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
zq
.
camellia
.
config
;
import
com.zq.common.annotation.AnonymousAccess
;
import
com.zq.common.config.base.SecurityProperties
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.utils.RequestMethodEnum
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpMethod
;
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.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.config.core.GrantedAuthorityDefaults
;
import
org.springframework.security.config.http.SessionCreationPolicy
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
java.util.*
;
/**
* @author Zheng Jie
*/
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
,
securedEnabled
=
true
)
public
class
SpringSecurityConfig
extends
WebSecurityConfigurerAdapter
{
private
final
TokenProvider
tokenProvider
;
private
final
JwtAuthenticationEntryPoint
authenticationErrorHandler
;
private
final
JwtAccessDeniedHandler
jwtAccessDeniedHandler
;
private
final
ApplicationContext
applicationContext
;
private
final
SecurityProperties
properties
;
private
final
RedisUtils
redisUtils
;
@Bean
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
// 去除 ROLE_ 前缀
return
new
GrantedAuthorityDefaults
(
""
);
}
@Bean
public
PasswordEncoder
passwordEncoder
()
{
// 密码加密方式
return
new
BCryptPasswordEncoder
();
}
@Override
protected
void
configure
(
HttpSecurity
httpSecurity
)
throws
Exception
{
// 搜寻匿名标记 url: @AnonymousAccess
RequestMappingHandlerMapping
requestMappingHandlerMapping
=
(
RequestMappingHandlerMapping
)
applicationContext
.
getBean
(
"requestMappingHandlerMapping"
);
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
=
requestMappingHandlerMapping
.
getHandlerMethods
();
// 获取匿名标记
Map
<
String
,
Set
<
String
>>
anonymousUrls
=
getAnonymousUrl
(
handlerMethodMap
);
httpSecurity
// 禁用 CSRF
.
csrf
().
disable
()
// .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
// 授权异常
.
exceptionHandling
()
.
authenticationEntryPoint
(
authenticationErrorHandler
)
.
accessDeniedHandler
(
jwtAccessDeniedHandler
)
// 防止iframe 造成跨域
.
and
()
.
headers
()
.
frameOptions
()
.
disable
()
// 不创建会话
.
and
()
.
sessionManagement
()
.
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
)
.
and
()
.
authorizeRequests
()
// 静态资源等等
.
antMatchers
(
HttpMethod
.
GET
,
"/*.html"
,
"/**/*.html"
,
"/**/*.css"
,
"/**/*.js"
,
"/webSocket/**"
).
permitAll
()
// swagger 文档
.
antMatchers
(
"/swagger-ui.html"
).
permitAll
()
.
antMatchers
(
"/swagger-resources/**"
).
permitAll
()
.
antMatchers
(
"/webjars/**"
).
permitAll
()
.
antMatchers
(
"/*/api-docs"
).
permitAll
()
// 文件
.
antMatchers
(
"/avatar/**"
).
permitAll
()
.
antMatchers
(
"/file/**"
).
permitAll
()
// 阿里巴巴 druid
.
antMatchers
(
"/druid/**"
).
permitAll
()
// 放行OPTIONS请求
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
// GET
.
antMatchers
(
HttpMethod
.
GET
,
anonymousUrls
.
get
(
RequestMethodEnum
.
GET
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// POST
.
antMatchers
(
HttpMethod
.
POST
,
anonymousUrls
.
get
(
RequestMethodEnum
.
POST
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// PUT
.
antMatchers
(
HttpMethod
.
PUT
,
anonymousUrls
.
get
(
RequestMethodEnum
.
PUT
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// PATCH
.
antMatchers
(
HttpMethod
.
PATCH
,
anonymousUrls
.
get
(
RequestMethodEnum
.
PATCH
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// DELETE
.
antMatchers
(
HttpMethod
.
DELETE
,
anonymousUrls
.
get
(
RequestMethodEnum
.
DELETE
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// 所有类型的接口都放行
.
antMatchers
(
anonymousUrls
.
get
(
RequestMethodEnum
.
ALL
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// 所有请求都需要认证
.
anyRequest
().
authenticated
()
.
and
().
apply
(
securityConfigurerAdapter
());
}
private
TokenConfigurer
securityConfigurerAdapter
()
{
return
new
TokenConfigurer
(
tokenProvider
,
properties
,
redisUtils
);
}
private
Map
<
String
,
Set
<
String
>>
getAnonymousUrl
(
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
)
{
Map
<
String
,
Set
<
String
>>
anonymousUrls
=
new
HashMap
<>(
6
);
Set
<
String
>
get
=
new
HashSet
<>();
Set
<
String
>
post
=
new
HashSet
<>();
Set
<
String
>
put
=
new
HashSet
<>();
Set
<
String
>
patch
=
new
HashSet
<>();
Set
<
String
>
delete
=
new
HashSet
<>();
Set
<
String
>
all
=
new
HashSet
<>();
for
(
Map
.
Entry
<
RequestMappingInfo
,
HandlerMethod
>
infoEntry
:
handlerMethodMap
.
entrySet
())
{
HandlerMethod
handlerMethod
=
infoEntry
.
getValue
();
AnonymousAccess
anonymousAccess
=
handlerMethod
.
getMethodAnnotation
(
AnonymousAccess
.
class
);
if
(
null
!=
anonymousAccess
)
{
List
<
RequestMethod
>
requestMethods
=
new
ArrayList
<>(
infoEntry
.
getKey
().
getMethodsCondition
().
getMethods
());
RequestMethodEnum
request
=
RequestMethodEnum
.
find
(
requestMethods
.
size
()
==
0
?
RequestMethodEnum
.
ALL
.
getType
()
:
requestMethods
.
get
(
0
).
name
());
switch
(
Objects
.
requireNonNull
(
request
))
{
case
GET:
get
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
case
POST:
post
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
case
PUT:
put
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
case
PATCH:
patch
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
case
DELETE:
delete
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
default
:
all
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
break
;
}
}
}
anonymousUrls
.
put
(
RequestMethodEnum
.
GET
.
getType
(),
get
);
anonymousUrls
.
put
(
RequestMethodEnum
.
POST
.
getType
(),
post
);
anonymousUrls
.
put
(
RequestMethodEnum
.
PUT
.
getType
(),
put
);
anonymousUrls
.
put
(
RequestMethodEnum
.
PATCH
.
getType
(),
patch
);
anonymousUrls
.
put
(
RequestMethodEnum
.
DELETE
.
getType
(),
delete
);
anonymousUrls
.
put
(
RequestMethodEnum
.
ALL
.
getType
(),
all
);
return
anonymousUrls
;
}
}
camellia-server/src/main/java/com/zq/camellia/config/TokenConfigurer.java
deleted
100644 → 0
View file @
2c50a1f0
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
zq
.
camellia
.
config
;
import
com.zq.common.config.base.SecurityProperties
;
import
com.zq.common.config.redis.RedisUtils
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.web.DefaultSecurityFilterChain
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
/**
* @author /
*/
@RequiredArgsConstructor
public
class
TokenConfigurer
extends
SecurityConfigurerAdapter
<
DefaultSecurityFilterChain
,
HttpSecurity
>
{
private
final
TokenProvider
tokenProvider
;
private
final
SecurityProperties
properties
;
private
final
RedisUtils
redisUtils
;
@Override
public
void
configure
(
HttpSecurity
http
)
{
TokenFilter
customFilter
=
new
TokenFilter
(
tokenProvider
,
properties
,
redisUtils
);
http
.
addFilterBefore
(
customFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
}
camellia-server/src/main/java/com/zq/camellia/config/TokenFilter.java
deleted
100644 → 0
View file @
2c50a1f0
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
zq
.
camellia
.
config
;
import
cn.hutool.core.util.StrUtil
;
import
com.zq.common.config.base.SecurityProperties
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.vo.OnlineUserDto
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.filter.GenericFilterBean
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.IOException
;
import
java.util.Objects
;
/**
* @author /
*/
public
class
TokenFilter
extends
GenericFilterBean
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
TokenFilter
.
class
);
private
final
TokenProvider
tokenProvider
;
private
final
SecurityProperties
properties
;
private
final
RedisUtils
redisUtils
;
/**
* @param tokenProvider Token
* @param properties JWT
* @param redisUtils redis
*/
public
TokenFilter
(
TokenProvider
tokenProvider
,
SecurityProperties
properties
,
RedisUtils
redisUtils
)
{
this
.
properties
=
properties
;
this
.
tokenProvider
=
tokenProvider
;
this
.
redisUtils
=
redisUtils
;
}
@Override
public
void
doFilter
(
ServletRequest
servletRequest
,
ServletResponse
servletResponse
,
FilterChain
filterChain
)
throws
IOException
,
ServletException
{
HttpServletRequest
httpServletRequest
=
(
HttpServletRequest
)
servletRequest
;
String
token
=
resolveToken
(
httpServletRequest
);
// 对于 Token 为空的不需要去查 Redis
if
(
StrUtil
.
isNotBlank
(
token
))
{
OnlineUserDto
onlineUserDto
=
null
;
boolean
cleanUserCache
=
false
;
try
{
onlineUserDto
=
redisUtils
.
getObj
(
properties
.
getOnlineKey
()
+
token
,
OnlineUserDto
.
class
);
}
catch
(
ExpiredJwtException
e
)
{
log
.
error
(
e
.
getMessage
());
cleanUserCache
=
true
;
}
finally
{
if
(
cleanUserCache
||
Objects
.
isNull
(
onlineUserDto
))
{
// userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY)));
}
}
if
(
onlineUserDto
!=
null
&&
StringUtils
.
hasText
(
token
))
{
Authentication
authentication
=
tokenProvider
.
getAuthentication
(
token
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
// Token 续期
tokenProvider
.
checkRenewal
(
token
);
}
}
filterChain
.
doFilter
(
servletRequest
,
servletResponse
);
}
/**
* 初步检测Token
*
* @param request /
* @return /
*/
private
String
resolveToken
(
HttpServletRequest
request
)
{
String
bearerToken
=
request
.
getHeader
(
properties
.
getHeader
());
if
(
StringUtils
.
hasText
(
bearerToken
)
&&
bearerToken
.
startsWith
(
properties
.
getTokenStartWith
()))
{
// 去掉令牌前缀
return
bearerToken
.
replace
(
properties
.
getTokenStartWith
(),
""
);
}
else
{
log
.
debug
(
"非法Token:{}"
,
bearerToken
);
}
return
null
;
}
}
camellia-server/src/main/java/com/zq/camellia/config/TokenProvider.java
deleted
100644 → 0
View file @
2c50a1f0
package
com
.
zq
.
camellia
.
config
;
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
cn.hutool.core.date.DateField
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.zq.common.config.base.SecurityProperties
;
import
com.zq.common.config.redis.RedisUtils
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SignatureAlgorithm
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.authority.SimpleGrantedAuthority
;
import
org.springframework.security.core.userdetails.User
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.StringUtils
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.xml.bind.DatatypeConverter
;
import
java.security.Key
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public
class
TokenProvider
implements
InitializingBean
{
private
final
RedisUtils
redisUtils
;
private
final
SecurityProperties
properties
;
public
static
final
String
AUTHORITIES_KEY
=
"auth"
;
private
static
Key
key
;
private
static
SignatureAlgorithm
signatureAlgorithm
;
@Override
public
void
afterPropertiesSet
()
{
signatureAlgorithm
=
SignatureAlgorithm
.
HS512
;
byte
[]
keyBytes
=
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
());
key
=
new
SecretKeySpec
(
keyBytes
,
signatureAlgorithm
.
getJcaName
());
}
public
static
String
createToken
(
Authentication
authentication
)
{
String
authorities
=
authentication
.
getAuthorities
().
stream
()
.
map
(
GrantedAuthority:
:
getAuthority
)
.
collect
(
Collectors
.
joining
(
","
));
return
Jwts
.
builder
()
.
setSubject
(
authentication
.
getName
())
.
claim
(
AUTHORITIES_KEY
,
authorities
)
.
signWith
(
signatureAlgorithm
,
key
)
// 加入ID确保生成的 Token 都不一致
.
setId
(
IdUtil
.
simpleUUID
())
.
compact
();
}
public
Claims
getClaims
(
String
token
)
{
return
Jwts
.
parser
()
.
setSigningKey
(
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
()))
.
parseClaimsJws
(
token
)
.
getBody
();
}
public
Authentication
getAuthentication
(
String
token
)
{
Claims
claims
=
Jwts
.
parser
()
.
setSigningKey
(
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
()))
.
parseClaimsJws
(
token
)
.
getBody
();
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
Object
authoritiesStr
=
claims
.
get
(
AUTHORITIES_KEY
);
Collection
<?
extends
GrantedAuthority
>
authorities
=
ObjectUtil
.
isNotEmpty
(
authoritiesStr
)
?
Arrays
.
stream
(
authoritiesStr
.
toString
().
split
(
","
))
.
map
(
SimpleGrantedAuthority:
:
new
)
.
collect
(
Collectors
.
toList
())
:
Collections
.
emptyList
();
User
principal
=
new
User
(
claims
.
getSubject
(),
"******"
,
authorities
);
return
new
UsernamePasswordAuthenticationToken
(
principal
,
token
,
authorities
);
}
/**
* @param token 需要检查的token
*/
public
void
checkRenewal
(
String
token
)
{
// 判断是否续期token,计算token的过期时间
long
time
=
redisUtils
.
getExpire
(
properties
.
getOnlineKey
()
+
token
)
*
1000
;
Date
expireDate
=
DateUtil
.
offset
(
new
Date
(),
DateField
.
MILLISECOND
,
(
int
)
time
);
// 判断当前时间与过期时间的时间差
long
differ
=
expireDate
.
getTime
()
-
System
.
currentTimeMillis
();
// 如果在续期检查的范围内,则续期
if
(
differ
<=
properties
.
getDetect
())
{
long
renew
=
time
+
properties
.
getRenew
();
redisUtils
.
expire
(
properties
.
getOnlineKey
()
+
token
,
renew
,
TimeUnit
.
MILLISECONDS
);
}
}
public
String
getToken
(
HttpServletRequest
request
)
{
String
bearerToken
=
request
.
getHeader
(
properties
.
getHeader
());
if
(
StringUtils
.
hasText
(
bearerToken
)
&&
bearerToken
.
startsWith
(
properties
.
getTokenStartWith
()))
{
// 去掉令牌前缀
return
bearerToken
.
replace
(
properties
.
getTokenStartWith
(),
""
);
}
return
null
;
}
}
camellia-server/src/main/resources/application.yml
deleted
100644 → 0
View file @
2c50a1f0
server
:
port
:
${camellia.port}
#配置数据源
spring
:
application
:
name
:
${camellia.name}
servlet
:
#上传文件限制
multipart
:
#单个文件大小
max-file-size
:
20MB
#设置总上传的数据大小
max-request-size
:
50MB
jackson
:
date-format
:
yyyy-MM-dd HH:mm:ss
time-zone
:
GMT+8
redis
:
#数据库索引
database
:
0
host
:
${redis.url}
port
:
${redis.port}
password
:
${redis.password}
#连接超时时间
timeout
:
5000
datasource
:
druid
:
db-type
:
com.alibaba.druid.pool.DruidDataSource
driverClassName
:
${jdbc.driver-class-name}
username
:
${jdbc.username}
password
:
${jdbc.password}
url
:
${jdbc.url}
# 初始连接数
initial-size
:
5
# 最小连接数
min-idle
:
10
# 最大连接数
max-active
:
20
# 获取连接超时时间
max-wait
:
5000
# 连接有效性检测时间
time-between-eviction-runs-millis
:
60000
# 连接在池中最小生存的时间
min-evictable-idle-time-millis
:
300000
# 连接在池中最大生存的时间
max-evictable-idle-time-millis
:
900000
test-while-idle
:
true
test-on-borrow
:
false
test-on-return
:
false
# 检测连接是否有效
validation-query
:
select 1
# 配置监控统计
webStatFilter
:
enabled
:
true
stat-view-servlet
:
enabled
:
true
url-pattern
:
/druid/*
reset-enable
:
false
filter
:
stat
:
enabled
:
true
# 记录慢SQL
log-slow-sql
:
true
slow-sql-millis
:
1000
merge-sql
:
true
wall
:
config
:
multi-statement-allow
:
true
# mybatis plus 配置
mybatis-plus
:
global-config
:
db-config
:
select-strategy
:
not_empty
update-strategy
:
not_empty
#logging.level.com.zq.drug.dao: debug
\ No newline at end of file
camellia-server/src/main/resources/bootstrap.yml
deleted
100644 → 0
View file @
2c50a1f0
spring
:
cloud
:
config
:
name
:
config
profile
:
@
profiles.active@
discovery
:
enabled
:
true
service-id
:
CONFIG-SERVER
uri
:
http://127.0.0.1:8300/
eureka
:
client
:
serviceUrl
:
defaultZone
:
http://admin:123456@127.0.0.1:8800/eureka/
cms-server/src/main/java/com/zq/cms/config/SpringSecurityConfig.java
View file @
0fa85449
...
@@ -74,6 +74,11 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -74,6 +74,11 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
=
requestMappingHandlerMapping
.
getHandlerMethods
();
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
=
requestMappingHandlerMapping
.
getHandlerMethods
();
// 获取匿名标记
// 获取匿名标记
Map
<
String
,
Set
<
String
>>
anonymousUrls
=
getAnonymousUrl
(
handlerMethodMap
);
Map
<
String
,
Set
<
String
>>
anonymousUrls
=
getAnonymousUrl
(
handlerMethodMap
);
Set
<
String
>
apiSet
=
new
HashSet
<>();
//不使用注解的时候在这添加url放行
// apiSet.add("/app/**");
anonymousUrls
.
put
(
"API"
,
apiSet
);
httpSecurity
httpSecurity
// 禁用 CSRF
// 禁用 CSRF
.
csrf
().
disable
()
.
csrf
().
disable
()
...
@@ -127,6 +132,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -127,6 +132,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.
antMatchers
(
HttpMethod
.
DELETE
,
anonymousUrls
.
get
(
RequestMethodEnum
.
DELETE
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
.
antMatchers
(
HttpMethod
.
DELETE
,
anonymousUrls
.
get
(
RequestMethodEnum
.
DELETE
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// 所有类型的接口都放行
// 所有类型的接口都放行
.
antMatchers
(
anonymousUrls
.
get
(
RequestMethodEnum
.
ALL
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
.
antMatchers
(
anonymousUrls
.
get
(
RequestMethodEnum
.
ALL
.
getType
()).
toArray
(
new
String
[
0
])).
permitAll
()
// API接口放行
.
antMatchers
(
anonymousUrls
.
get
(
"API"
).
toArray
(
new
String
[
0
])).
permitAll
()
// 所有请求都需要认证
// 所有请求都需要认证
.
anyRequest
().
authenticated
()
.
anyRequest
().
authenticated
()
.
and
().
apply
(
securityConfigurerAdapter
());
.
and
().
apply
(
securityConfigurerAdapter
());
...
...
common-utils/src/main/java/com/zq/common/config/limit/LimitAspect.java
View file @
0fa85449
...
@@ -69,9 +69,9 @@ public class LimitAspect {
...
@@ -69,9 +69,9 @@ public class LimitAspect {
if
(
limitType
==
LimitType
.
IP
)
{
if
(
limitType
==
LimitType
.
IP
)
{
key
=
HttpRequestUtils
.
getClientIp
(
request
);
key
=
HttpRequestUtils
.
getClientIp
(
request
);
}
else
{
}
else
{
key
=
signatureMethod
.
getName
();
key
=
signatureMethod
.
getName
();
// 获取方法名
if
(
"sendCode"
.
equals
(
key
))
{
if
(
"sendCode"
.
equals
(
key
))
{
key
=
(
String
)
joinPoint
.
getArgs
()[
0
];
key
=
(
String
)
joinPoint
.
getArgs
()[
0
];
// 获取方法的第一个参数
}
}
}
}
}
}
...
...
common-utils/src/main/java/com/zq/common/utils/UploadUtils.java
View file @
0fa85449
package
com
.
zq
.
common
.
utils
;
package
com
.
zq
.
common
.
utils
;
import
com.zq.common.exception.BusinessException
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.io.FileUtils
;
import
org.apache.commons.io.FileUtils
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.text.SimpleDateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.Objects
;
import
java.util.Objects
;
...
@@ -34,7 +38,7 @@ public class UploadUtils {
...
@@ -34,7 +38,7 @@ public class UploadUtils {
return
"/images/"
+
systemName
+
yyyyMMdd
+
name
;
return
"/images/"
+
systemName
+
yyyyMMdd
+
name
;
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
log
.
error
(
"图保存失败:{}"
,
e
.
getMessage
());
log
.
error
(
"图保存失败:{}"
,
e
.
getMessage
());
return
"图保存失败"
;
throw
new
BusinessException
(
"图保存失败"
)
;
}
}
}
}
...
@@ -56,8 +60,72 @@ public class UploadUtils {
...
@@ -56,8 +60,72 @@ public class UploadUtils {
return
"/file/"
+
systemName
+
yyyyMMdd
+
name
;
return
"/file/"
+
systemName
+
yyyyMMdd
+
name
;
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
log
.
error
(
"文件保存失败:{}"
,
e
.
getMessage
());
log
.
error
(
"文件保存失败:{}"
,
e
.
getMessage
());
return
"文件保存失败"
;
throw
new
BusinessException
(
"文件保存失败"
)
;
}
}
}
}
/**
* 保存临时图片
*
* @param file
* @param systemName
* @return
*/
public
static
String
saveTempImage
(
MultipartFile
file
,
String
systemName
)
{
try
{
String
originalFilename
=
file
.
getOriginalFilename
();
//取文件扩展名
String
ext
=
Objects
.
requireNonNull
(
originalFilename
).
substring
(
originalFilename
.
lastIndexOf
(
"."
)
+
1
);
AssertUtils
.
isImgExt
(
ext
,
"图片格式不正确"
);
//生成新文件名
String
name
=
UuidUtils
.
uuidNoDash
()
+
"."
+
ext
;
String
yyyyMMdd
=
new
SimpleDateFormat
(
DATE_FORMAT
).
format
(
new
Date
());
File
dest
=
new
File
(
"/images/temp/"
+
systemName
+
yyyyMMdd
+
name
);
FileUtils
.
writeByteArrayToFile
(
dest
,
file
.
getBytes
());
return
"/images/temp/"
+
systemName
+
yyyyMMdd
+
name
;
}
catch
(
IOException
e
)
{
log
.
error
(
"图保存失败:{}"
,
e
.
getMessage
());
throw
new
BusinessException
(
"图保存失败"
);
}
}
/**
* 保存临时文件
*
* @return
*/
public
static
String
saveTempFile
(
MultipartFile
file
,
String
systemName
)
{
try
{
String
originalFilename
=
file
.
getOriginalFilename
();
//取文件扩展名
String
ext
=
Objects
.
requireNonNull
(
originalFilename
).
substring
(
originalFilename
.
lastIndexOf
(
"."
)
+
1
);
//生成新文件名
String
name
=
UuidUtils
.
uuidNoDash
()
+
"."
+
ext
;
String
yyyyMMdd
=
new
SimpleDateFormat
(
DATE_FORMAT
).
format
(
new
Date
());
File
dest
=
new
File
(
"/file/temp/"
+
systemName
+
yyyyMMdd
+
name
);
FileUtils
.
writeByteArrayToFile
(
dest
,
file
.
getBytes
());
return
"/file/temp/"
+
systemName
+
yyyyMMdd
+
name
;
}
catch
(
IOException
e
)
{
log
.
error
(
"文件保存失败:{}"
,
e
.
getMessage
());
throw
new
BusinessException
(
"文件保存失败"
);
}
}
public
static
String
tempToFormal
(
String
tempPath
)
{
Path
path
=
Paths
.
get
(
tempPath
);
File
formal
=
new
File
(
tempPath
.
replace
(
"/temp"
,
""
));
try
{
FileUtils
.
writeByteArrayToFile
(
formal
,
Files
.
readAllBytes
(
path
));
Files
.
delete
(
path
);
}
catch
(
IOException
e
)
{
log
.
error
(
"文件转存失败:{}"
,
e
.
getMessage
());
throw
new
BusinessException
(
"文件转存失败"
);
}
return
tempPath
.
replace
(
"/temp"
,
""
);
}
/*public static void main(String[] args) {
System.out.println(tempToFormal("/images/temp/supply/202101/14/3ca51d7873044443be912e83209c4406.png"));
}*/
}
}
eureka-server/pom.xml
View file @
0fa85449
...
@@ -16,6 +16,10 @@
...
@@ -16,6 +16,10 @@
<groupId>
org.springframework.cloud
</groupId>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-server
</artifactId>
<artifactId>
spring-cloud-starter-netflix-eureka-server
</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-security
</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
eureka-server/src/main/java/com/zq/eureka/config/WebSecurityConfig.java
0 → 100644
View file @
0fa85449
package
com
.
zq
.
eureka
.
config
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
@EnableWebSecurity
@Configuration
public
class
WebSecurityConfig
extends
WebSecurityConfigurerAdapter
{
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
csrf
().
disable
();
http
.
authorizeRequests
().
anyRequest
().
authenticated
().
and
().
httpBasic
();
}
}
file-server/src/main/java/com/zq/file/controller/AccessController.java
0 → 100644
View file @
0fa85449
package
com
.
zq
.
file
.
controller
;
import
io.swagger.annotations.Api
;
import
org.springframework.core.io.FileSystemResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.ContentDisposition
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.imageio.ImageIO
;
import
javax.servlet.http.HttpServletRequest
;
import
java.awt.image.BufferedImage
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
@Api
(
tags
=
"访问图片文件"
)
@RestController
@RequestMapping
(
"/"
)
public
class
AccessController
{
@GetMapping
(
value
=
"/images/**"
,
produces
=
MediaType
.
IMAGE_JPEG_VALUE
)
public
BufferedImage
getImage
(
HttpServletRequest
request
)
throws
IOException
{
try
(
InputStream
is
=
new
FileInputStream
(
request
.
getRequestURI
()))
{
return
ImageIO
.
read
(
is
);
}
}
@GetMapping
(
value
=
"/file/**"
)
public
ResponseEntity
<
Resource
>
download
(
HttpServletRequest
request
)
{
String
contentDisposition
=
ContentDisposition
.
builder
(
"attachment"
)
.
filename
(
request
.
getRequestURI
())
.
build
().
toString
();
return
ResponseEntity
.
ok
()
.
header
(
HttpHeaders
.
CONTENT_DISPOSITION
,
contentDisposition
)
.
contentType
(
MediaType
.
APPLICATION_OCTET_STREAM
)
.
body
(
new
FileSystemResource
(
request
.
getRequestURI
()));
}
}
file-server/src/main/java/com/zq/file/controller/FileController.java
View file @
0fa85449
...
@@ -4,72 +4,41 @@ import com.zq.common.utils.AssertUtils;
...
@@ -4,72 +4,41 @@ import com.zq.common.utils.AssertUtils;
import
com.zq.common.utils.UploadUtils
;
import
com.zq.common.utils.UploadUtils
;
import
com.zq.common.vo.ResultVo
;
import
com.zq.common.vo.ResultVo
;
import
com.zq.common.vo.UploadVo
;
import
com.zq.common.vo.UploadVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.core.io.FileSystemResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.ContentDisposition
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.imageio.ImageIO
;
@Api
(
tags
=
"上传相关"
)
import
javax.servlet.http.HttpServletRequest
;
import
java.awt.image.BufferedImage
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
@RestController
@RestController
@RequestMapping
(
"/"
)
@RequestMapping
(
"/
file
"
)
public
class
FileController
{
public
class
FileController
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
FileController
.
class
);
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
FileController
.
class
);
/**
@ApiOperation
(
"上传文件"
)
* 上传文件
@RequestMapping
(
value
=
"/uploadFile"
)
*
* @return
*/
@RequestMapping
(
value
=
"/file/uploadFile"
)
public
ResultVo
<
String
>
uploadFile
(
UploadVo
file
)
{
public
ResultVo
<
String
>
uploadFile
(
UploadVo
file
)
{
log
.
info
(
"文件入口上传开始:{}"
,
""
);
log
.
info
(
"文件入口上传开始:{}"
,
""
);
AssertUtils
.
hasText
(
file
.
getSystemName
(),
"字段:systemName 系统名不能为空"
);
AssertUtils
.
hasText
(
file
.
getSystemName
(),
"字段:systemName 系统名不能为空"
);
return
ResultVo
.
success
(
UploadUtils
.
saveFile
(
file
.
getFile
(),
file
.
getSystemName
()));
return
ResultVo
.
success
(
UploadUtils
.
saveFile
(
file
.
getFile
(),
file
.
getSystemName
()));
}
}
/**
@ApiOperation
(
"上传文件"
)
* 上传文件
@RequestMapping
(
value
=
"/uploadImage"
)
*
* @return
*/
@RequestMapping
(
value
=
"/file/uploadImage"
)
public
ResultVo
<
String
>
uploadImage
(
UploadVo
file
)
{
public
ResultVo
<
String
>
uploadImage
(
UploadVo
file
)
{
log
.
info
(
"图片入口上传开始:{}"
,
""
);
log
.
info
(
"图片入口上传开始:{}"
,
""
);
AssertUtils
.
hasText
(
file
.
getSystemName
(),
"字段:systemName 系统名不能为空"
);
AssertUtils
.
hasText
(
file
.
getSystemName
(),
"字段:systemName 系统名不能为空"
);
return
ResultVo
.
success
(
UploadUtils
.
saveImg
(
file
.
getFile
(),
file
.
getSystemName
()));
return
ResultVo
.
success
(
UploadUtils
.
saveImg
(
file
.
getFile
(),
file
.
getSystemName
()));
}
}
@GetMapping
(
value
=
"/images/**"
,
produces
=
MediaType
.
IMAGE_JPEG_VALUE
)
@ApiOperation
(
"临时文件转正式文件"
)
public
BufferedImage
getImage
(
HttpServletRequest
request
)
throws
IOException
{
@RequestMapping
(
"/tempToFormal"
)
try
(
InputStream
is
=
new
FileInputStream
(
request
.
getRequestURI
()))
{
public
ResultVo
<
String
>
tempToFormal
(
String
filePath
)
{
return
ImageIO
.
read
(
is
);
AssertUtils
.
hasText
(
filePath
,
"文件地址不能为空"
);
}
return
ResultVo
.
success
(
UploadUtils
.
tempToFormal
(
filePath
));
}
@GetMapping
(
value
=
"/file/**"
)
public
ResponseEntity
<
Resource
>
download
(
HttpServletRequest
request
)
{
String
contentDisposition
=
ContentDisposition
.
builder
(
"attachment"
)
.
filename
(
request
.
getRequestURI
())
.
build
().
toString
();
return
ResponseEntity
.
ok
()
.
header
(
HttpHeaders
.
CONTENT_DISPOSITION
,
contentDisposition
)
.
contentType
(
MediaType
.
APPLICATION_OCTET_STREAM
)
.
body
(
new
FileSystemResource
(
request
.
getRequestURI
()));
}
}
}
}
pom.xml
View file @
0fa85449
...
@@ -35,7 +35,6 @@
...
@@ -35,7 +35,6 @@
<module>
config-server
</module>
<module>
config-server
</module>
<module>
common-utils
</module>
<module>
common-utils
</module>
<module>
sys-server
</module>
<module>
sys-server
</module>
<module>
camellia-server
</module>
<module>
cms-server
</module>
<module>
cms-server
</module>
<module>
file-server
</module>
<module>
file-server
</module>
</modules>
</modules>
...
...
Write
Preview
Markdown
is supported
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