#### 介绍
系统架构搭建过程
#### 软件架构
软件架构说明
采用maven模块化搭建项目架构
#### 安装教程
1. java version "19.0.2"
2. Apache Maven 3.9.0
3. mysql 8.0
4. git version 2.24.3 (Apple Git-128)
#### 使用说明
1. frameword 存放所有技术相关的子module
core 所有核心模块 全局代码
web 处理web请求 全局代码
2. server 存放所有业务相关的子module
一、父模块icloudp-parent
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.9.RELEASE
com.icloudp
icloudp-parent
1.0
t-pan-parent
项目服务端
framework
server
pom
19
UTF-8
UTF-8
1.8
1.8
1.8
1.1.10
8.0.11
3.3.2
2.3
2.9.8
20.0
3.5
3.2.1
1.2.56
0.7.0
2.4
2.8.0
1.9.3
4.5.18
0.9.10
1.26.1-RELEASE
2.8.3
2.0.3
1.5.2.Final
1.18.20
0.2.0
org.reflections
reflections
${reflections.version}
mysql
mysql-connector-java
runtime
${mysql-connector.version}
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus.version}
com.baomidou
mybatis-plus-generator
${mybatis-plus.version}
org.apache.velocity
velocity-engine-core
${velocity.version}
com.fasterxml.jackson.core
jackson-annotations
${jackson.version}
com.google.guava
guava
${guava.version}
org.apache.commons
commons-lang3
${commons-lang3.version}
commons-collections
commons-collections
${commons-collections.version}
commons-io
commons-io
${commons-io.version}
com.alibaba
fastjson
${fastjson.version}
io.jsonwebtoken
jjwt
${jjwt.version}
io.springfox
springfox-swagger2
${swagger2.version}
io.springfox
springfox-swagger-ui
${swagger2.version}
com.github.xiaoymin
swagger-bootstrap-ui
${swagger2.ui.version}
cn.hutool
hutool-core
${hutool.version}
com.github.tobato
fastdfs-client
${fastdfs.client.version}
com.aliyun.oss
aliyun-sdk-oss
${oss.client.version}
org.apache.rocketmq
rocketmq-spring-boot-starter
${rocketmq.version}
org.mapstruct
mapstruct
${org.mapstruct.version}
com.github.ben-manes.caffeine
caffeine
${caffeine.version}
org.projectlombok
lombok
${projectlombok.version}
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
19
utf-8
true
org.codehaus.mojo
versions-maven-plugin
2.7
org.apache.maven.plugins
maven-assembly-plugin
2.6
org.apache.maven.plugins
maven-jar-plugin
3.1.2
子模块 framework-core
pom.xml
4.0.0
com.icloudp
icloudp-framework
1.0
icloudp-core
19
19
UTF-8
com.fasterxml.jackson.core
jackson-annotations
com.google.guava
guava
org.apache.commons
commons-lang3
commons-collections
commons-collections
commons-io
commons-io
com.alibaba
fastjson
io.jsonwebtoken
jjwt
cn.hutool
hutool-core
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-actuator
org.mapstruct
mapstruct
子模块icloudp-web
pom.xml
4.0.0
com.icloudp
icloudp-framework
1.0
t-pan-web
19
19
UTF-8
com.icloudp
icloudp-core
1.0
org.springframework.boot
spring-boot-starter-web
3.0.4
子模块server
pom.xml
4.0.0
com.icloudp
icloudp-parent
1.0
com.ticloudp
icloudp-server
19
19
UTF-8
com.think.pan
t-pan-web
1.0
org.springframework.boot
spring-boot-autoconfigure
t-pan-server
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
org.mapstruct
mapstruct-processor
${org.mapstruct.version}
org.projectlombok
lombok
${projectlombok.version}
org.projectlombok
lombok-mapstruct-binding
${lombok-mapstruct-binding.version}
org.apache.maven.plugins
maven-jar-plugin
true
true
org.springframework.boot
spring-boot-maven-plugin
com.think.pan.server.TPanServerLauncher
ZIP
repackage
core 模块封装请求响应
public class RSP implements Serializable {
/**
* 状态码
*/
private int code ;
/**
* 状态说明
*/
private String message ;
/**
* 返回数据承载
*/
private T data;
private RSP(Integer code){
this.code = code;
}
private RSP(Integer code,String message){
this.code = code;
this.message = message;
}
private RSP(Integer code,String message ,T data){
this.code = code;
this.message = message;
this.data = data;
}
/**
* 序列化时,忽略此方法
* @return
*/
@JsonIgnore
@JSONField(serialize = false)
public boolean isSuccess(){
return Objects.equals(this.code,Responsecode.SUCCESS.getCode());
}
public static RSP success(){
return new RSP(Responsecode.SUCCESS.getCode());
}
public static RSP success(String message){
return new RSP(Responsecode.SUCCESS.getCode(),message);
}
public static RSP success(String message,T data){
return new RSP(Responsecode.SUCCESS.getCode(),message,data);
}
public static RSP fail(){
return new RSP(Responsecode.ERROR.getCode(),Responsecode.ERROR.getDesc());
}
public static RSP fail(String error_message){
return new RSP(Responsecode.ERROR.getCode(),error_message);
}
public static RSP fail(int error_code ,String error_message){
return new RSP(error_code,error_message);
}
public static RSP fail(Responsecode responsecode){
return new RSP(responsecode.getCode(),responsecode.getDesc());
}
}
响应代码封装
public enum Responsecode {
/**
* 成功
*/
SUCCESS(0, "SUCCESS"),
/**
* 错误
*/
ERROR(1, "ERROR"),
/**
* token过期
*/
TOKEN_EXPIRE(2, "TOKEN_EXPIRE"),
/**
* 参数错误
*/
ERROR_PARAM(3, "ERROR_PARAM"),
/**
* 无权限访问
*/
ACCESS_DENIED(4, "ACCESS_DENIED"),
/**
* 需要登录
*/
NEED_LOGIN(10, "NEED_LOGIN");
/**
* 状态码
*/
private Integer code;
/**
* 描述信息
*/
private String desc;
}
异常处理
public class BusinesException extends RuntimeException{
/**
* 错误码
*/
private Integer code;
/**
* 错误信息
*/
private String message;
public BusinesException(Responsecode responsecode) {
this.code = responsecode.getCode();
this.message = responsecode.getDesc();
}
public BusinesException(String message, Integer code) {
this.code = code;
this.message = message;
}
public BusinesException(String message) {
this.code = Responsecode.ERROR_PARAM.getCode();
this.message = message;
}
public BusinesException() {
this.code = Responsecode.ERROR_PARAM.getCode();
this.message = Responsecode.ERROR_PARAM.getDesc();
}
}
工具类
public class JwtUtil {
public static final Long TWO_LONG = 2L;
/**
* 秘钥
*/
private final static String JWT_PRIVATE_KEY = "0CB16040A41140E48F2F93A7BE222C46";
/**
* 刷新时间
*/
private final static String RENEWAL_TIME = "RENEWAL_TIME";
/**
* 生成token
*
* @param subject
* @param claimKey
* @param claimValue
* @param expire
* @return
*/
public static String generateToken(String subject, String claimKey, Object claimValue, Long expire) {
String token = Jwts.builder()
.setSubject(subject)
.claim(claimKey, claimValue)
.claim(RENEWAL_TIME, new Date(System.currentTimeMillis() + expire / TWO_LONG))
.setExpiration(new Date(System.currentTimeMillis() + expire))
.signWith(SignatureAlgorithm.HS256, JWT_PRIVATE_KEY)
.compact();
return token;
}
/**
* 解析token
*
* @param token
* @return
*/
public static Object analyzeToken(String token, String claimKey) {
if (StringUtils.isBlank(token)) {
return null;
}
try {
Claims claims = Jwts.parser()
.setSigningKey(JWT_PRIVATE_KEY)
.parseClaimsJws(token)
.getBody();
return claims.get(claimKey);
} catch (Exception e) {
return null;
}
}
}
web 模块 跨域处理 过滤器
public class CrossFilter implements Filter {
/**
* 添加跨域的响应头
*
* @param response
*/
private void addCrossResponseHeader(HttpServletResponse response) {
response.setHeader(CrossConfigEnum.Cross_ORIGIN.getKey(), CrossConfigEnum.Cross_ORIGIN.getValue());
response.setHeader(CrossConfigEnum.Cross_CREDENTIALS.getKey(), CrossConfigEnum.Cross_CREDENTIALS.getValue());
response.setHeader(CrossConfigEnum.Cross_METHODS.getKey(), CrossConfigEnum.Cross_METHODS.getValue());
response.setHeader(CrossConfigEnum.Cross_MAX_AGE.getKey(), CrossConfigEnum.Cross_MAX_AGE.getValue());
response.setHeader(CrossConfigEnum.Cross_HEADERS.getKey(), CrossConfigEnum.Cross_HEADERS.getValue());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
addCrossResponseHeader(response);
filterChain.doFilter(servletRequest,servletResponse);
}
/**
* 跨域设置枚举类
*/
@AllArgsConstructor
@Getter
public enum CrossConfigEnum {
/**
* 允许所有远程访问
*/
Cross_ORIGIN("Access-Control-Allow-Origin", "*"),
/**
* 允许认证
*/
Cross_CREDENTIALS("Access-Control-Allow-Credentials", "true"),
/**
* 允许远程调用的请求类型
*/
Cross_METHODS("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"),
/**
* 指定本次预检请求的有效期,单位是秒
*/
Cross_MAX_AGE("Access-Control-Max-Age", "3600"),
/**
* 允许所有请求头
*/
Cross_HEADERS("Access-Control-Allow-Headers", "*");
private String key;
private String value;
}
}
yaml 文件
spring:
application:
name: icloudp
output:
ansi:
enabled: always
mvc:
servlet:
load-on-startup: 1
servlet:
multipart:
max-file-size: 4000MB
max-request-size: 4000MB
server:
port: 80
management:
endpoints:
web:
exposure:
include: '*'
exclude: env,beans