
这个项目是一个典型的Spring Boot 后端项目结构,各个文件 / 目录的作用和联系可以按 "分层架构" 来理解,核心是实现用户相关的业务功能(比如注册、登录、用户管理)。
一、各目录 / 文件的作用
1. config 目录:配置类
-
WebConfig.java:用于配置 Web 相关的功能,比如跨域(CORS)、拦截器、静态资源映射、消息转换器等。作用是 "定制 Spring Boot 的 Web 行为",让项目符合业务的 HTTP 请求 / 响应规则。javapackage com.example.modi.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { // 1. 对所有以/api开头的接口生效跨域规则 registry.addMapping("/api/**") // 2. 允许所有来源的跨域请求 .allowedOriginPatterns("*") // 3. 允许的HTTP请求方法(覆盖前端常用的GET/POST/PUT/DELETE,OPTIONS是预检请求) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 4. 允许请求中携带所有请求头(比如Token、Content-Type等) .allowedHeaders("*") // 5. 允许携带Cookie/认证信息(比如前端请求时带token到Cookie里) .allowCredentials(true); } }
2. controller 目录:控制器(接口层)
负责接收前端的 HTTP 请求,调用 Service 层处理业务,返回响应结果。
AuthController.java:处理 "认证 / 授权" 相关的接口,比如用户登录、登出等请求。UserController.java:处理 "用户管理" 相关的接口,比如用户列表查询、创建用户、修改用户、删除用户 等请求。
java
package com.example.modi.controller;
import com.example.modi.dto.LoginRequest;
import com.example.modi.dto.LoginResponse;
import com.example.modi.service.AuthService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final AuthService authService;
public AuthController(AuthService authService) {
this.authService = authService;
}
@PostMapping("/login")
public LoginResponse login(@RequestBody LoginRequest req) {
return authService.login(req);
}
}
java
package com.example.modi.controller;
import com.example.modi.dto.CreateUserRequest;
import com.example.modi.dto.UpdateUserRequest;
import com.example.modi.model.User;
import com.example.modi.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<User> list(@RequestParam(value = "q", required = false) String q) {
return userService.list(q);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void create(@RequestBody CreateUserRequest req) {
userService.create(req);
}
@PutMapping("/{id}")
public void update(@PathVariable("id") String id, @RequestBody UpdateUserRequest req) {
userService.update(id, req);
}
@DeleteMapping("/{id}")
public void delete(@PathVariable("id") String id) {
userService.delete(id);
}
}
AuthController 和 UserController 是 Spring Boot 项目中处理前端 HTTP 请求的核心接口层,分别负责 "用户认证" 和 "用户资源管理" 相关的接口实现,是前后端交互的桥梁。
核心定位:Controller 类的通用作用
这两个类都标注了 @RestController,本质是接收前端 HTTP 请求 → 调用 Service 层处理业务逻辑 → 返回 JSON 格式的响应(或状态码),不处理具体业务,只做 "请求转发" 和 "参数接收 / 响应封装"。
逐类解析:
- AuthController:用户认证接口控制器
负责处理登录相关的接口,是用户进入系统的 "入口",核心是身份校验。
| 注解 / 代码 | 具体作用 |
|---|---|
@RequestMapping("/api/auth") |
定义接口前缀,区分 "认证接口" 和 "用户管理接口",避免接口路径冲突 |
@PostMapping("/login") |
仅接收 POST 请求(符合登录接口的 RESTful 规范),路径是 /api/auth/login |
@RequestBody |
接收前端传递的 JSON 格式登录参数(比如 {"login": "admin", "password": "123456"}),并自动封装到 LoginRequest 对象中 |
调用 authService.login(req) |
把业务逻辑交给 Service 层处理(Controller 不写业务,符合分层架构原则) |
返回 LoginResponse |
把 Service 处理后的结果(比如 token、用户信息)以 JSON 返给前端 |
- UserController:用户资源管理接口控制器
负责处理用户列表查询、创建、修改、删除等 "用户资源 CRUD" 接口,是系统对用户数据的核心管理入口,遵循 RESTful 设计规范。
| 注解 / 代码 | 具体作用 |
|---|---|
@GetMapping |
接收 GET 请求,路径是 /api/users,用于查询资源(符合 RESTful 规范) |
@RequestParam(value = "q", required = false) |
接收 URL 中的可选参数(比如 /api/users?q=张三),required = false 表示不传 q 也能访问 |
@PostMapping + @ResponseStatus(HttpStatus.CREATED) |
接收 POST 请求创建用户,返回 201 状态码(而非默认 200),符合 "创建资源返回 201" 的 REST 规范 |
@PutMapping("/{id}") |
接收 PUT 请求修改用户,{id} 是路径参数(RESTful 中用路径标识要修改的资源) |
@PathVariable("id") |
提取 URL 路径中的 id 值(比如 /api/users/123 中的 123),传给 Service 层 |
@DeleteMapping("/{id}") |
接收 DELETE 请求删除用户,同样用路径参数指定要删除的用户 ID |
简单来说,Controller 就是 "前端的请求找对人,后端的结果送出去",不做具体业务,只做 "传话筒" 和 "参数校验员"(复杂校验还是在 Service 层)。
3. dto 目录:数据传输对象(Data Transfer Object)
用于前后端 / 层与层之间的数据传递 ,只包含需要传输的字段(避免直接暴露数据库模型)。
CreateUserRequest.java:前端 "创建用户" 时传过来的参数(比如 id、name、password 等),对应之前代码里的create接口入参。LoginRequest.java:前端 "登录" 时传的参数(比如用户名 / 密码、邮箱等)。LoginResponse.java:登录成功后返回给前端的结果(比如 token、用户基本信息等)。UpdateUserRequest.java:前端 "修改用户" 时传的参数(比如要修改的用户名、头像等)。
java
package com.example.modi.dto;
import lombok.Data;
import java.time.LocalDate;
/**
* 创建用户的请求DTO
* 使用Lombok的@Data注解替代手动编写的getter/setter/构造器等方法
*/
@Data // 核心注解:自动生成所有字段的getter、setter、toString、equals、hashCode
public class CreateUserRequest {
// 保留所有字段定义,无需手动写getter/setter/构造器
private String id;
private String name;
private String password;
private String avatar;
private LocalDate birthday;
private String email;
}
java
package com.example.modi.dto;
import lombok.Data;
/**
* 登录请求DTO
* @Data 自动生成getter、setter、空参构造、toString、equals、hashCode
*/
@Data
public class LoginRequest {
private String username;
private String password;
}
java
package com.example.modi.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 登录响应DTO
* @Getter:仅生成getter(响应DTO无需setter,只读)
* @AllArgsConstructor:生成包含所有字段的有参构造器(对应原有new LoginResponse(id, name))
*/
@Getter
@AllArgsConstructor
public class LoginResponse {
private String id;
private String name;
}
java
package com.example.modi.dto;
import lombok.Data;
import java.time.LocalDate;
/**
* 更新用户请求DTO
* @Data 自动生成getter、setter、空参构造、toString、equals、hashCode
*/
@Data
public class UpdateUserRequest {
private String name;
private LocalDate birthday;
private String email;
private String avatar;
}
| 注解 | 作用 | 适用场景 |
|---|---|---|
@Data |
组合注解:@Getter+@Setter+@ToString+@EqualsAndHashCode+ 空参构造(字段非 final 时) |
请求 DTO(需要 getter/setter + 空参构造) |
@Getter |
仅生成所有字段的 getter 方法 | 响应 DTO(只读,无需 setter) |
@AllArgsConstructor |
生成包含所有字段的有参构造器 | 响应 DTO(需要传入参数初始化) |
为什么 LoginResponse 不用 @Data?LoginResponse 是 "响应 DTO",前端只接收数据,不需要修改,因此仅需 getter、无需 setter;原有代码只有有参构造,用@AllArgsConstructor正好匹配,符合 "只读 DTO" 的最佳实践。
4. mapper 目录:数据访问层(MyBatis/Mapper 接口)
负责直接操作数据库,定义 SQL 相关的方法(通常配合 MyBatis,通过注解或 XML 写 SQL)。
UserMapper.java:定义用户相关的数据库操作,比如list(查询用户列表)、findById(根据 ID 查用户)、insert(新增用户)、updateName(修改用户名)、deleteById(删除用户)等方法。
java
package com.example.modi.mapper;
import com.example.modi.model.AuthUser;
import com.example.modi.model.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
@Select({
"<script>",
"SELECT id, name, avatar, birthday, email",
"FROM users",
"<where>",
" <if test='q != null and q.trim() != \"\"'>",
" (id LIKE CONCAT('%', #{q}, '%')",
" OR name LIKE CONCAT('%', #{q}, '%')",
" OR email LIKE CONCAT('%', #{q}, '%'))",
" </if>",
"</where>",
"ORDER BY id ASC",
"</script>"
})
List<User> list(@Param("q") String q);
@Select("SELECT id, name, avatar, birthday, email FROM users WHERE id = #{id}")
User findById(@Param("id") String id);
@Select({
"SELECT id, name, password",
"FROM users",
"WHERE id = #{login} OR name = #{login} OR email = #{login}",
"LIMIT 1"
})
AuthUser findAuthByLogin(@Param("login") String login);
@Insert("INSERT INTO users (id, name, password, avatar, birthday, email) VALUES (#{id}, #{name}, #{password}, #{avatar}, #{birthday}, #{email})")
int insert(@Param("id") String id,
@Param("name") String name,
@Param("password") String password,
@Param("avatar") String avatar,
@Param("birthday") java.time.LocalDate birthday,
@Param("email") String email);
@Update("UPDATE users SET name = #{name} WHERE id = #{id}")
int updateName(@Param("id") String id, @Param("name") String name);
@Update("UPDATE users SET name = #{name}, birthday = #{birthday}, email = #{email}, avatar = #{avatar} WHERE id = #{id}")
int updateUser(@Param("id") String id,
@Param("name") String name,
@Param("birthday") java.time.LocalDate birthday,
@Param("email") String email,
@Param("avatar") String avatar);
@Delete("DELETE FROM users WHERE id = #{id}")
int deleteById(@Param("id") String id);
}
5. model 目录:实体类(数据库模型)
对应数据库中的表结构,每个类的字段和数据库表的列一一对应。
User.java:对应 "用户表" 的实体,包含用户的所有字段(id、name、password、email 等),是数据库数据在代码中的映射。AuthUser.java:通常是 "认证用的用户模型",可能包含登录态、权限等信息(比如 Spring Security 的用户对象)。
6. service 目录:业务逻辑层
UserService.java:业务接口,定义用户相关的业务方法(比如list、create、updateName、delete)。UserServiceImpl.java:接口的实现类,核心业务逻辑的载体 :- 调用
UserMapper操作数据库; - 做参数校验(比如之前代码里的 "id 不能为空");
- 处理业务异常(比如用户已存在、用户不存在)。
- 调用
7. ModiApplication.java:项目启动类
Spring Boot 的入口类,用@SpringBootApplication注解标记,运行这个类就能启动整个项目。
8. resources 目录:资源文件
application.properties:项目的配置文件,比如数据库连接信息(URL、用户名、密码)、服务器端口(比如 8080)、MyBatis 配置等。schema.sql:数据库表结构的 SQL 脚本,Spring Boot 启动时会自动执行这个文件,创建对应的表(比如user表)。static/templates:通常放静态资源(比如前端 JS/CSS)或模板文件(比如 Thymeleaf 页面),但这个项目可能是纯后端接口,所以这两个目录可能暂时没用。
二、各层的联系(请求处理流程)
以 "创建用户" 为例,整个流程是:
- 前端发送 "创建用户" 的 HTTP 请求 → 被
UserController接收; UserController调用UserService的create方法,并传入CreateUserRequest(前端参数);UserServiceImpl(UserService的实现类):- 先校验
CreateUserRequest的参数是否合法; - 调用
UserMapper的findById检查用户是否已存在; - 调用
UserMapper的insert方法,把用户数据插入数据库;
- 先校验
UserMapper执行对应的 SQL 语句,操作数据库;- 最终结果通过
UserController返回给前端。
简单说:Controller 接收请求 → Service 处理业务 → Mapper 操作数据库,而 DTO 负责传递数据、Model 对应数据库表、Config 负责配置、Application 是启动入口。