【Java实战㉞】从0到1:Spring Boot Web开发与接口设计实战
目录
- 一、Spring Boot Web 基础配置
- 1.1 Web 起步依赖(spring-boot-starter-web 导入与核心组件)
- 1.2 内置服务器配置(Tomcat 端口、线程池、连接超时设置)
- 1.3 静态资源访问(静态资源存放路径、自定义资源映射)
- 1.4 全局异常处理(@ControllerAdvice、@ExceptionHandler 统一异常响应)
- 二、RESTful 接口开发
- 2.1 RESTful 设计规范(HTTP 方法、URL 命名、状态码使用)
- 2.2 核心注解使用(@RestController、@RequestMapping、@GetMapping 等)
- 2.3 请求参数处理(@RequestParam、@PathVariable、@RequestBody)
- 2.4 响应结果封装(统一响应格式、JSON 数据返回)
- 三、接口参数校验与文档
- 3.1 参数校验框架(Hibernate Validator,@NotNull、@NotBlank 等注解)
- 3.2 自定义参数校验注解(实现 Validator 接口)
- 3.3 Swagger/OpenAPI 整合(接口文档自动生成、在线测试)
- 3.4 接口实战案例(用户管理 CRUD 接口开发与测试)
一、Spring Boot Web 基础配置
1.1 Web 起步依赖(spring-boot-starter-web 导入与核心组件)
在 Spring Boot 项目中,若要快速搭建 Web 应用,spring-boot-starter-web起步依赖必不可少。以 Maven 项目为例,在pom.xml文件的<dependencies>标签内添加如下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
当我们添加此依赖后,Maven 会利用依赖传递特性,自动引入 Web 开发所需的众多依赖。其中核心组件之一便是 Spring MVC,它是 Spring 框架中用于构建 Web 应用的模块,基于 MVC(Model - View - Controller)设计模式。在 Spring MVC 中,Controller 负责处理用户请求,Model 封装业务数据,View 负责展示数据给用户。例如,我们定义一个 Controller 来处理用户对首页的请求:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;@Controller
public class HomeController {@GetMapping("/")public String home(Model model) {model.addAttribute("message", "欢迎来到我的Spring Boot应用");return "index";}
}
上述代码中,@GetMapping(“/”)注解表示当用户访问根路径时,会调用home方法,该方法将数据添加到Model中,并返回视图名index,Spring MVC 会根据视图解析器找到对应的视图页面展示给用户。spring-boot-starter-web还引入了 Tomcat 作为默认的嵌入式 Web 服务器,使得我们无需额外配置和部署外部 Web 服务器,就能快速启动并运行 Web 应用。
1.2 内置服务器配置(Tomcat 端口、线程池、连接超时设置)
Spring Boot 默认使用 Tomcat 作为内置服务器,默认端口为 8080。若要修改端口,在application.properties文件中添加如下配置即可:
server.port=8081
或者在application.yml文件中配置:
server:port: 8081
合理配置 Tomcat 线程池参数对于提升应用的并发处理能力至关重要。主要参数包括:
- server.tomcat.max-threads:最大线程数,默认值为 200,即 Tomcat 可同时处理的最大线程数量。例如,在高并发场景下,若发现线程数经常达到上限,导致请求处理缓慢,可以适当增大此值,如设置为 500。在application.yml中的配置如下:
server:tomcat:max-threads: 500
- server.tomcat.min-spare-threads:最小空闲线程数,默认值为 10 ,Tomcat 启动时初始化的线程数,即使没有请求时也会保留这些线程,以便快速响应新请求。
- server.tomcat.accept-count:等待队列长度,默认值为 100 ,当所有线程都在忙碌时,新请求会进入等待队列,该参数表示队列的最大长度。若队列满了,新请求将被拒绝。
连接超时设置决定了客户端与服务器建立连接以及数据传输的最长等待时间。通过设置server.connection-timeout参数可以配置连接超时时间,单位为毫秒,默认值为 - 1,表示不限制超时时间。例如,设置连接超时时间为 5 秒:
server:connection-timeout: 5000
合适的连接超时设置能避免因长时间等待无效连接而占用资源,提高系统的稳定性和资源利用率。
1.3 静态资源访问(静态资源存放路径、自定义资源映射)
Spring Boot 默认会从src/main/resources/static、src/main/resources/public、src/main/resources/resources以及src/main/resources/META-INF/resources目录下查找并加载静态资源。例如,将图片、CSS、JavaScript 文件等放置在src/main/resources/static目录下,当用户访问http://localhost:8080/images/logo.png时,Spring Boot 会自动从src/main/resources/static/images目录下查找logo.png文件并返回给用户。
若想自定义静态资源映射路径,可通过实现WebMvcConfigurer接口来完成。比如,我们希望将/static-resources/路径映射到src/main/resources/custom-static/目录下,代码如下:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static-resources/**").addResourceLocations("classpath:/custom-static/");}
}
上述配置完成后,当用户访问http://localhost:8080/static-resources/js/app.js时,Spring Boot 会从src/main/resources/custom-static/js目录下查找app.js文件,实现了灵活的静态资源访问路径自定义。
1.4 全局异常处理(@ControllerAdvice、@ExceptionHandler 统一异常响应)
在 Web 开发中,统一处理异常能提升系统的稳定性和用户体验。@ControllerAdvice注解用于定义全局异常处理类,它会对所有标注了@RequestMapping注解的方法进行异常处理。@ExceptionHandler注解用于指定处理特定异常的方法。
例如,创建一个全局异常处理器:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<String> handleException(Exception e) {e.printStackTrace();return new ResponseEntity<>("服务器内部错误", HttpStatus.INTERNAL_SERVER_ERROR);}
}
上述代码中,GlobalExceptionHandler类被@ControllerAdvice注解修饰,成为全局异常处理器。@ExceptionHandler(Exception.class)表示该方法处理所有未捕获的Exception异常。当系统中任何Controller方法抛出Exception异常时,都会被该方法捕获,并返回一个包含错误信息和500 Internal Server Error状态码的响应给客户端,实现了异常响应的统一处理。
二、RESTful 接口开发
2.1 RESTful 设计规范(HTTP 方法、URL 命名、状态码使用)
在当今的 Web 开发领域,RESTful 架构风格的接口设计已成为主流,它通过合理使用 HTTP 方法、规范 URL 命名以及恰当运用状态码,使接口具备更好的可读性、可维护性和可扩展性。
在 HTTP 方法的使用上,GET 方法用于获取资源,就像从图书馆书架上取下一本书查看内容,比如请求GET /users/1,表示获取 ID 为 1 的用户信息;POST 方法用于创建新资源,如同在图书馆添加一本新书,如发送POST /users并携带用户信息来创建新用户;PUT 方法用于更新资源,类似于修改图书馆中某本书的信息,如PUT /users/1,携带更新后的用户数据来全量更新 ID 为 1 的用户信息;DELETE 方法用于删除资源,好比从图书馆移除一本书,如DELETE /users/1删除 ID 为 1 的用户。每种方法都有其明确的语义和使用场景,避免了使用不恰当的方法导致接口语义混乱。
URL 命名遵循一定规则能让接口更清晰易懂。URL 应使用名词表示资源,并且通常采用复数形式,例如/users表示用户资源集合,/orders表示订单资源集合。避免在 URL 中出现动词,因为对资源的操作应由 HTTP 方法体现,而不是将操作写在 URL 里。比如获取用户列表不应写成/getUsers,而应是GET /users。同时,URL 路径应简洁明了,避免深度嵌套和冗长的命名,可采用小写字母和连字符分隔单词,如/product-categories表示产品分类资源。
状态码在接口中起到重要的沟通作用,它能让客户端快速了解请求的处理结果。2xx 状态码表示成功,其中 200 OK 表示请求成功,获取资源时常用,如GET /products/1成功返回产品信息时状态码为 200;201 Created 表示资源创建成功,POST /users成功创建用户后返回 201,并在响应头的 Location 字段中指明新创建资源的 URL;204 No Content 表示请求成功但无内容返回,常用于DELETE /users/1成功删除用户后,不需要返回数据时。4xx 状态码表示客户端错误,400 Bad Request 表示客户端请求参数错误,如请求GET /users?id=abc,id参数格式错误时返回 400;401 Unauthorized 表示未授权,需要身份验证,常用于访问需要登录的资源时;404 Not Found 表示请求的资源不存在,如请求GET /users/999,而 ID 为 999 的用户不存在则返回 404。5xx 状态码表示服务器错误,500 Internal Server Error 表示服务器内部出现错误,当服务器执行代码出错时返回该状态码,告知客户端服务器端出现问题。
2.2 核心注解使用(@RestController、@RequestMapping、@GetMapping 等)
在 Spring Boot 的 RESTful 接口开发中,@RestController、@RequestMapping、@GetMapping等注解发挥着关键作用,它们简化了接口开发流程,使代码结构更加清晰。
@RestController是一个组合注解,它结合了@Controller和@ResponseBody的功能。@Controller用于标识一个类为 Spring MVC 的控制器,负责处理 HTTP 请求;@ResponseBody则表示该控制器方法的返回值将直接作为 HTTP 响应体返回,而不会被解析为视图。例如:
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {// 控制器方法
}
上述代码中,UserController被@RestController注解修饰,表明该类中的方法返回值会直接以 JSON 等格式返回给客户端,无需额外配置视图解析器。
@RequestMapping是一个通用的请求映射注解,可用于类和方法上。标注在类上时,表示类中的所有响应请求的方法都是以该类路径为父路径;标注在方法上时,指定该方法处理的具体 URL 路径和 HTTP 请求方法等。例如:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/users")
public class UserController {@RequestMapping(value = "/{id}", method = RequestMethod.GET)public String getUserById(@PathVariable Long id) {// 根据id获取用户信息的逻辑return "获取到用户ID: " + id;}
}
在这个例子中,@RequestMapping(“/users”)表示UserController处理所有以/users为前缀的 URL 请求,而@RequestMapping(value = “/{id}”, method = RequestMethod.GET)则表示getUserById方法处理GET请求,具体路径为/users/{id},即根据用户 ID 获取用户信息。
@GetMapping是@RequestMapping(method = RequestMethod.GET)的缩写,用于处理 HTTP GET 请求,使代码更加简洁易读。例如:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/users")
public class UserController {@GetMapping("/list")public String listUsers() {// 获取用户列表的逻辑return "用户列表";}
}
这里@GetMapping(“/list”)清晰地表明listUsers方法处理GET请求,路径为/users/list,专门用于获取用户列表。类似地,@PostMapping、@PutMapping、@DeleteMapping分别是对应POST、PUT、DELETE请求的缩写注解,在开发中可根据不同的 HTTP 请求方法选择合适的注解来映射请求。
2.3 请求参数处理(@RequestParam、@PathVariable、@RequestBody)
在处理 RESTful 接口请求时,准确获取和处理请求参数至关重要,@RequestParam、@PathVariable、@RequestBody这三个注解为我们提供了便捷的方式来获取不同类型的请求参数。
@RequestParam用于从请求参数中获取值,请求参数是 URL 中?后面的键值对。它可以将这些参数的值绑定到方法的参数上,并且可以指定参数是否必须存在以及默认值。例如:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ProductController {@GetMapping("/products")public String getProductsByPrice(@RequestParam(value = "minPrice", defaultValue = "0") double minPrice,@RequestParam(value = "maxPrice", required = false) Double maxPrice) {// 根据价格范围获取产品的逻辑String result = "获取价格大于等于 " + minPrice;if (maxPrice != null) {result += " 且小于等于 " + maxPrice + " 的产品";} else {result += " 的产品";}return result;}
}
上述代码中,@RequestParam(“minPrice”)获取请求参数minPrice的值,若请求中未提供该参数,则使用默认值0;@RequestParam(“maxPrice”)获取请求参数maxPrice的值,required = false表示该参数不是必须的,若请求中没有该参数,maxPrice的值为null。
@PathVariable用于从 URI 模板变量中获取值,URI 模板变量是在 URI 中用大括号{}包围的变量名。它通常与@GetMapping、@PostMapping等注解一起使用,将 URL 中的变量值绑定到方法参数上。例如:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@GetMapping("/orders/{orderId}")public String getOrderById(@PathVariable Long orderId) {// 根据订单ID获取订单信息的逻辑return "获取到订单ID: " + orderId;}
}
当请求GET /orders/123时,@PathVariable Long orderId会将 URL 中的123赋值给orderId参数,方便后续根据订单 ID 进行业务处理。
@RequestBody用于将 HTTP 请求体中的 JSON 或 XML 数据绑定到方法的参数上,通常用于处理客户端发送的复杂数据类型,如对象或数组,这些数据会被自动转换为 Java 对象。它常与@PostMapping或@PutMapping等注解一起使用,因为这两种 HTTP 方法通常用于提交数据。例如:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@PostMapping("/users")public String createUser(@RequestBody User user) {// 保存用户信息的逻辑return "创建用户成功: " + user.getName();}
}class User {private String name;private int age;// 省略getter和setter方法
}
当客户端发送POST /users请求,并在请求体中携带 JSON 格式的用户数据,如{“name”: “张三”, “age”: 20}时,Spring 会自动将这些数据转换为User对象,并传递给createUser方法中的user参数,实现对复杂数据的处理。
2.4 响应结果封装(统一响应格式、JSON 数据返回)
在 RESTful 接口开发中,统一的响应格式能提高接口的易用性和可维护性,便于前端或其他客户端进行处理。同时,将数据以 JSON 格式返回是目前 Web 开发中广泛采用的方式,因为 JSON 具有轻量级、易解析的特点。
首先,定义一个统一的响应类,例如:
public class ResponseResult<T> {private int code;private String message;private T data;public ResponseResult(int code, String message, T data) {this.code = code;this.message = message;this.data = data;}// 省略getter和setter方法
}
这个ResponseResult类包含三个字段:code表示响应状态码,用于标识请求处理的结果,例如 200 表示成功,400 表示请求错误等;message是对响应结果的描述信息,如 “操作成功”“参数错误” 等,方便前端了解具体情况;data则是实际返回的数据,类型通过泛型T表示,可以是任何 Java 对象,如用户信息、订单列表等。
在控制器方法中,使用这个统一响应类来封装响应结果。例如:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class BookController {@GetMapping("/books/1")public ResponseResult<Book> getBook() {Book book = new Book("Java核心技术", "Cay S. Horstmann");return new ResponseResult<>(200, "获取书籍成功", book);}
}class Book {private String title;private String author;public Book(String title, String author) {this.title = title;this.author = author;}// 省略getter和setter方法
}
上述代码中,getBook方法返回一个ResponseResult<Book>对象,将书籍信息封装在其中,状态码设置为 200,消息为 “获取书籍成功”。
在 Spring Boot 中,默认会使用Jackson库将 Java 对象转换为 JSON 格式返回给客户端。当客户端接收到这个响应时,会得到如下格式的 JSON 数据:
{"code": 200,"message": "获取书籍成功","data": {"title": "Java核心技术","author": "Cay S. Horstmann"}
}
这种统一的响应格式和 JSON 数据返回方式,使得前端开发人员能够方便地解析和处理接口响应,提高了前后端交互的效率和稳定性,同时也便于在项目中进行错误处理和日志记录等操作。
三、接口参数校验与文档
3.1 参数校验框架(Hibernate Validator,@NotNull、@NotBlank 等注解)
在接口开发中,确保输入参数的合法性至关重要,Hibernate Validator 作为一款强大的参数校验框架,为 Java 开发者提供了便捷的校验方式。它实现了 Java Bean Validation 规范,使得我们能够通过简单的注解来定义校验规则。
首先,在 Spring Boot 项目中引入spring-boot-starter-validation依赖,它包含了 Hibernate Validator 相关的依赖。若使用 Maven 构建项目,在pom.xml文件中添加如下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
添加依赖后,便可以在实体类或请求参数对象中使用校验注解。@NotNull注解用于确保字段不为null,它适用于各种对象类型,包括基本数据类型的包装类。例如:
import javax.validation.constraints.NotNull;public class User {@NotNull(message = "用户ID不能为空")private Long id;// 省略其他字段和方法
}
上述代码中,@NotNull注解标注在id字段上,当对User对象进行校验时,如果id为null,则会抛出校验异常,并返回message中定义的错误信息 “用户 ID 不能为空”。
@NotBlank注解专门用于字符串类型,它要求字符串不为null,并且去除首尾空格后长度大于 0。例如:
import javax.validation.constraints.NotBlank;public class User {@NotBlank(message = "用户名不能为空")private String username;// 省略其他字段和方法
}
这里,若username为null、空字符串或者仅包含空格,校验都会失败,提示 “用户名不能为空”,常用于校验用户名、密码等重要字符串信息,确保其有实际内容。
在控制器方法中,使用@Valid或@Validated注解来触发校验。例如:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
@Validated
public class UserController {@PostMapping("/users")public String createUser(@Validated @RequestBody User user) {// 保存用户逻辑return "用户创建成功";}
}
当客户端发送POST /users请求,请求体中包含User对象数据时,Spring 会自动对user对象进行校验。若参数不满足校验规则,会抛出MethodArgumentNotValidException异常,我们可以通过全局异常处理器来统一处理这类异常,返回友好的错误提示给客户端,确保接口接收到的数据是符合预期的,提高系统的稳定性和健壮性。
3.2 自定义参数校验注解(实现 Validator 接口)
尽管 Hibernate Validator 提供了丰富的内置校验注解,但在实际开发中,有时内置注解无法满足复杂的业务需求,这时就需要自定义参数校验注解。通过实现Validator接口,我们可以创建符合特定业务规则的校验逻辑。
首先,定义自定义校验注解。例如,我们希望校验一个字符串是否为手机号码格式,创建一个@PhoneNumber注解:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface PhoneNumber {String message() default "手机号码格式不正确";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
上述代码中,@Retention(RetentionPolicy.RUNTIME)表示该注解在运行时有效;@Target指定了注解可以作用的目标,这里是字段和方法参数;@Constraint(validatedBy = PhoneNumberValidator.class)指定了校验器类为PhoneNumberValidator。
接下来,实现PhoneNumberValidator校验器类,它需要实现ConstraintValidator接口:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;public class PhoneNumberValidator implements ConstraintValidator<PhoneNumber, String> {private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");@Overridepublic void initialize(PhoneNumber constraintAnnotation) {// 初始化方法,可用于获取注解参数等操作}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (value == null) {return true;}return PHONE_PATTERN.matcher(value).matches();}
}
在isValid方法中,通过正则表达式匹配来判断传入的字符串是否符合手机号码格式。如果匹配成功,返回true表示校验通过;否则返回false,校验失败。
最后,在实体类或请求参数对象中使用自定义注解:
public class User {@PhoneNumberprivate String phone;// 省略其他字段和方法
}
这样,当对User对象进行校验时,若phone字段的值不符合手机号码格式,就会触发自定义的校验逻辑,返回@PhoneNumber注解中定义的错误信息 “手机号码格式不正确”,从而实现了满足特定业务需求的参数校验功能。
3.3 Swagger/OpenAPI 整合(接口文档自动生成、在线测试)
在接口开发过程中,生成清晰、准确的接口文档对于团队协作和接口的维护至关重要。Swagger 和 OpenAPI 为我们提供了便捷的方式来自动生成接口文档,并支持在线测试功能,大大提高了接口开发的效率和可维护性。
Swagger 2 整合
以 Spring Boot 项目为例,首先在pom.xml文件中添加 Swagger 2 相关依赖:
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>3.0.0</version>
</dependency>
添加依赖后,创建一个 Swagger 配置类,用于配置 Swagger 的相关参数:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket api() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("Spring Boot API 文档").description("这是一个Spring Boot项目的接口文档").version("1.0").build();}
}
在上述配置类中,@EnableSwagger2注解启用 Swagger 2 功能;Docket定义了 Swagger 的基本配置,apiInfo方法设置了接口文档的标题、描述和版本信息;RequestHandlerSelectors.basePackage指定了需要生成接口文档的控制器所在的包路径,PathSelectors.any()表示对所有路径生成文档。
启动项目后,访问http://localhost:8080/swagger-ui.html,即可看到自动生成的 Swagger 接口文档页面。在该页面中,可以查看每个接口的详细信息,包括请求方法、URL、请求参数、响应参数等,并且可以直接在页面上进行接口测试,输入请求参数,发送请求并查看响应结果,方便开发人员进行接口调试和验证。
OpenAPI 整合(以 springdoc-openapi 为例)
若使用 OpenAPI 进行接口文档生成,同样先在pom.xml文件中添加依赖:
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-ui</artifactId><version>1.5.9</version>
</dependency>
springdoc-openapi 的配置相对简单,通常只需在application.properties或application.yml文件中进行一些基本配置即可启用:
springdoc.api-docs.enabled=true
springdoc.swagger-ui.enabled=true
springdoc.swagger-ui.path=/swagger-ui.html
上述配置中,springdoc.api-docs.enabled=true启用 API 文档功能,springdoc.swagger-ui.enabled=true启用 Swagger UI 界面,springdoc.swagger-ui.path=/swagger-ui.html指定 Swagger UI 的访问路径。
启动项目后,同样通过http://localhost:8080/swagger-ui.html访问接口文档页面,OpenAPI 会根据项目中的控制器和接口定义,自动生成符合 OpenAPI 3.0 规范的接口文档,其功能与 Swagger 2 类似,但在文档生成和规范支持上可能有所不同,开发人员可根据项目需求选择合适的工具来生成接口文档。
3.4 接口实战案例(用户管理 CRUD 接口开发与测试)
通过一个用户管理 CRUD 接口开发的实战案例,能更好地理解和运用前面讲解的知识,展示完整的接口开发流程,并进行测试验证。
项目搭建与依赖引入
首先创建一个 Spring Boot 项目,在pom.xml文件中引入必要的依赖,包括spring-boot-starter-web、spring-boot-starter-validation(用于参数校验)以及数据库相关依赖(这里以 MySQL 和 MyBatis-Plus 为例):
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
</dependencies>
数据库表设计
创建一个user表,用于存储用户信息:
CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,password VARCHAR(100) NOT NULL,age INT,email VARCHAR(100)
);
实体类与 Mapper 层
创建User实体类,对应数据库中的user表:
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {private Long id;@NotBlank(message = "用户名不能为空")private String username;@NotBlank(message = "密码不能为空")private String password;private Integer age;@Email(message = "邮箱格式不正确")private String email;
}
使用 MyBatis-Plus 创建UserMapper接口,继承BaseMapper<User>,即可获得基本的 CRUD 操作方法:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {
}
服务层与控制器层
在服务层创建UserService接口及其实现类UserServiceImpl,用于处理业务逻辑:
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.User;public interface UserService extends IService<User> {
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
在控制器层创建UserController,实现用户管理的 CRUD 接口:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/users")
@Api(tags = "用户管理接口")
public class UserController {@Autowiredprivate UserService userService;@PostMapping@ApiOperation("创建用户")public String createUser(@Validated @RequestBody User user) {if (userService.save(user)) {return "用户创建成功";}return "用户创建失败";}@GetMapping("/{id}")@ApiOperation("根据ID查询用户")public User getUserById(@PathVariable Long id) {return userService.getById(id);}@GetMapping@ApiOperation("查询用户列表")public Page<User> getUserList(@RequestParam(defaultValue = "1") long current,@RequestParam(defaultValue = "10") long size) {Page<User> page = new Page<>(current, size);return userService.page(page, null);}@PutMapping@ApiOperation("更新用户")public String updateUser(@Validated @RequestBody User user) {if (userService.updateById(user)) {return "用户更新成功";}return "用户更新失败";}@DeleteMapping("/{id}")@ApiOperation("删除用户")public String deleteUser(@PathVariable Long id) {if (userService.removeById(id)) {return "用户删除成功";}return "用户删除失败";}
}
在上述控制器代码中,使用了前面讲解的各种注解,如@Validated用于参数校验,@Api和@ApiOperation用于 Swagger 接口文档描述,@RequestParam、@PathVariable、@RequestBody用于请求参数处理。
接口测试
启动项目后,通过 Swagger 界面进行接口测试。在 Swagger 页面中,可以清晰地看到每个接口的信息,包括请求方法、参数、响应等。例如,测试创建用户接口时,在 Swagger 页面输入合法的用户信息,点击 “Try it out” 按钮发送请求,若参数校验通过且业务逻辑执行成功,会返回 “用户创建成功” 的提示;若参数不符合校验规则,会返回相应的错误信息。同样,可以对查询、更新和删除接口进行测试,验证接口的正确性和稳定性,确保用户管理 CRUD 接口能够正常工作。