#### 介绍
系统架构搭建过程
#### 软件架构
软件架构说明
采用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
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icloudp</groupId>
<artifactId>icloudp-parent</artifactId>
<version>1.0</version>
<name>t-pan-parent</name>
<description>项目服务端</description>
<modules>
<module>framework</module>
<module>server</module>
</modules>
<packaging>pom</packaging>
<properties>
<java.version>19</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<druid.version>1.1.10</druid.version>
<mysql-connector.version>8.0.11</mysql-connector.version>
<mybatis-plus.version>3.3.2</mybatis-plus.version>
<velocity.version>2.3</velocity.version>
<jackson.version>2.9.8</jackson.version>
<guava.version>20.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections.version>3.2.1</commons-collections.version>
<fastjson.version>1.2.56</fastjson.version>
<jjwt.version>0.7.0</jjwt.version>
<commons-io.version>2.4</commons-io.version>
<swagger2.version>2.8.0</swagger2.version>
<swagger2.ui.version>1.9.3</swagger2.ui.version>
<hutool.version>4.5.18</hutool.version>
<reflections.version>0.9.10</reflections.version>
<fastdfs.client.version>1.26.1-RELEASE</fastdfs.client.version>
<oss.client.version>2.8.3</oss.client.version>
<rocketmq.version>2.0.3</rocketmq.version>
<org.mapstruct.version>1.5.2.Final</org.mapstruct.version>
<projectlombok.version>1.18.20</projectlombok.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
<dependencyManagement>
<dependencies>
<!--reflections 处理反射及动态生成内容-->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>${mysql-connector.version}</version>
</dependency>
<!--mybatis-plus-spring-boot-starter-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--json序列化-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--guava-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!--commons-lang3-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!--commons-collections-->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--jjwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger2.ui.version}</version>
</dependency>
<!--hutool-core-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--国人好用的工具集-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${fastdfs.client.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${oss.client.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!-- 本地缓存-->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<!--工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${projectlombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>19</source>
<target>19</target>
<encoding>utf-8</encoding>
<skip>true</skip>
</configuration>
</plugin>
<!--版本管理插件-->
<!--统一修改版本号:mvn versions:set -DnewVersion=1.0.1-SNAPSHOT -->
<!--提交版本号:mvn versions:commit-->
<!--回退版本号:mvn versions:revert-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
</build>
</project>
子模块 framework-core
pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.icloudp</groupId>
<artifactId>icloudp-framework</artifactId>
<version>1.0</version>
</parent>
<artifactId>icloudp-core</artifactId>
<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--json序列化-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!--guava-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!--commons-lang3-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--commons-collections-->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!--jjwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!--hutool-core-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<!--基础容器依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
</dependencies>
</project>
子模块icloudp-web
pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.icloudp</groupId>
<artifactId>icloudp-framework</artifactId>
<version>1.0</version>
</parent>
<artifactId>t-pan-web</artifactId>
<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.icloudp</groupId>
<artifactId>icloudp-core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.4</version>
</dependency>
</dependencies>
</project>
子模块server
pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.icloudp</groupId>
<artifactId>icloudp-parent</artifactId>
<version>1.0</version>
</parent>
<groupId>com.ticloudp</groupId>
<artifactId>icloudp-server</artifactId>
<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.think.pan</groupId>
<artifactId>t-pan-web</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
<build>
<finalName>t-pan-server</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${projectlombok.version}</version>
</path>
<!-- This is needed when using Lombok 1.18.16 and above -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.think.pan.server.TPanServerLauncher</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
core 模块封装请求响应
public class RSP<T> 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 <T> RSP<T> success(){
return new RSP<T>(Responsecode.SUCCESS.getCode());
}
public static <T> RSP<T> success(String message){
return new RSP<T>(Responsecode.SUCCESS.getCode(),message);
}
public static <T> RSP<T> success(String message,T data){
return new RSP<T>(Responsecode.SUCCESS.getCode(),message,data);
}
public static <T> RSP<T> fail(){
return new RSP<T>(Responsecode.ERROR.getCode(),Responsecode.ERROR.getDesc());
}
public static <T> RSP<T> fail(String error_message){
return new RSP<T>(Responsecode.ERROR.getCode(),error_message);
}
public static <T> RSP<T> fail(int error_code ,String error_message){
return new RSP<T>(error_code,error_message);
}
public static <T> RSP<T> fail(Responsecode responsecode){
return new RSP<T>(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