feat(chaos-api): 初始化项目基础结构
- 新增 ApiResult 类用于统一返回结果 - 添加应用配置文件和日志配置文件 - 配置 MyBatis-Plus 和 Druid 数据源 - 实现基本的安全配置,包括未授权和权限不足的处理 - 引入必要的依赖,如 lombok、fastjson2、MariaDB驱动等
This commit is contained in:
@@ -19,5 +19,15 @@
|
|||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package cn.nopj.chaos_api.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ApiResult<T> {
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
private String msg;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> ApiResult<T> success(T data) {
|
||||||
|
return new ApiResult<>(200, "success", data);
|
||||||
|
}
|
||||||
|
public static <T> ApiResult<T> success(String msg, T data) {
|
||||||
|
return new ApiResult<>(200, msg, data);
|
||||||
|
}
|
||||||
|
public static <T> ApiResult<T> failed(int code, String msg) {
|
||||||
|
return new ApiResult<>(code, msg, null);
|
||||||
|
}
|
||||||
|
public static <T> ApiResult<T> failed(String msg) {
|
||||||
|
return new ApiResult<>(500, msg, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,5 +40,15 @@
|
|||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mariadb.jdbc</groupId>
|
||||||
|
<artifactId>mariadb-java-client</artifactId>
|
||||||
|
<version>3.5.4</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package cn.nopj.chaos_api.config;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@MapperScan("cn.nopj.chaos_api.mapper")
|
||||||
|
public class MyBatisPlusConfig {
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.nopj.chaos_api.config.sec;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
@Override
|
||||||
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
|
||||||
|
ApiResult<Object> result = ApiResult.failed("未授权");
|
||||||
|
|
||||||
|
String string = JSONObject.toJSONString(result);
|
||||||
|
response.getWriter().print(string);
|
||||||
|
response.getWriter().flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package cn.nopj.chaos_api.config.sec;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RestfulAccessDeniedHandler implements AccessDeniedHandler {
|
||||||
|
@Override
|
||||||
|
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 状态码 403
|
||||||
|
|
||||||
|
ApiResult<String> result = ApiResult.failed(HttpServletResponse.SC_FORBIDDEN, "权限不足,请联系管理员");
|
||||||
|
|
||||||
|
response.getWriter().println(JSONObject.toJSONString( result));
|
||||||
|
response.getWriter().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package cn.nopj.chaos_api.config.sec;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
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.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||||
|
private final RestfulAccessDeniedHandler restfulAccessDeniedHandler;
|
||||||
|
|
||||||
|
public SecurityConfig(RestAuthenticationEntryPoint restAuthenticationEntryPoint, RestfulAccessDeniedHandler restfulAccessDeniedHandler) {
|
||||||
|
this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
|
||||||
|
this.restfulAccessDeniedHandler = restfulAccessDeniedHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
// 允许所有对 /api/public/** 的匿名访问
|
||||||
|
.requestMatchers("/api/public/**").permitAll()
|
||||||
|
// 其他所有请求都需要认证
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
// 禁用 CSRF,因为现代前后端分离项目通常使用 Token
|
||||||
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
|
.exceptionHandling(e -> e
|
||||||
|
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||||
|
.accessDeniedHandler(restfulAccessDeniedHandler))
|
||||||
|
;
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
28
chaos_api_web/src/main/resources/application.yaml
Normal file
28
chaos_api_web/src/main/resources/application.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
server:
|
||||||
|
port: 18888
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: chaos-api
|
||||||
|
datasource:
|
||||||
|
driver-class-name: org.mariadb.jdbc.Driver
|
||||||
|
url: jdbc:mysql://10.91.3.23:3306/chaos?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false
|
||||||
|
username: chaos
|
||||||
|
password: zx123456..
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
druid:
|
||||||
|
initial-size: 5
|
||||||
|
min-idle: 5
|
||||||
|
max-active: 20
|
||||||
|
max-wait: 60000
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
type-aliases-package: cn.nopj.chaos_api_domain.entity
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: assign_id
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|
||||||
38
chaos_api_web/src/main/resources/log4j2-spring.xml
Normal file
38
chaos_api_web/src/main/resources/log4j2-spring.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="INFO">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
|
||||||
|
<RollingFile name="RollingFile"
|
||||||
|
fileName="logs/chaos-api.log"
|
||||||
|
filePattern="logs/chaos-api-%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
|
<PatternLayout>
|
||||||
|
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
|
||||||
|
</PatternLayout>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy/>
|
||||||
|
<SizeBasedTriggeringPolicy size="10 MB"/>
|
||||||
|
</Policies>
|
||||||
|
<DefaultRolloverStrategy max="10"/>
|
||||||
|
</RollingFile>
|
||||||
|
</Appenders>
|
||||||
|
|
||||||
|
<Loggers>
|
||||||
|
<Logger name="org.springframework" level="info" additivity="false">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="RollingFile"/>
|
||||||
|
</Logger>
|
||||||
|
|
||||||
|
<Logger name="cn.nopj" level="debug" additivity="false">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="RollingFile"/>
|
||||||
|
</Logger>
|
||||||
|
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="RollingFile"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
26
pom.xml
26
pom.xml
@@ -87,6 +87,32 @@
|
|||||||
<artifactId>mybatis-plus</artifactId>
|
<artifactId>mybatis-plus</artifactId>
|
||||||
<version>3.5.12</version>
|
<version>3.5.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>1.2.25</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mariadb.jdbc</groupId>
|
||||||
|
<artifactId>mariadb-java-client</artifactId>
|
||||||
|
<version>3.5.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>2.0.57</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.38</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
</project>
|
</project>
|
||||||
Reference in New Issue
Block a user