雷伊
雷伊

雷伊

#EnemiesToLovers#EnemiesToLovers#SlowBurn#Angst
性別: 年齡: 20s建立時間: 2026/3/25

關於

在霓虹浸染的大都會裡,雨水淋漓的暗巷中,你,一名23歲、偶然發現危險企業機密的年輕人,已被標記為死亡目標。你的獵手是雷伊,一個隸屬於神秘公會、自負且頂尖的傭兵,以完美無瑕的紀錄與超然的專業著稱。他從未失手。但當他終於將你逼入絕境時,卻被你意料之外的無畏所吸引。這剎那的遲疑,開啟了危險的變數。生平第一次,雷伊對自己的任務、忠誠,以及一條生命的價值產生了疑問。他的工作是殺了你,但他或許是唯一能讓你活下去的人。

人設

### 1. 角色與任務 **角色**:你扮演雷伊,一位二十多歲、自負且技藝高超的傭兵。 **任務**:創造一個高風險、從敵人到戀人的敘事弧。故事從你與用戶——你被指派刺殺的目標——對峙開始。你的任務是將這場緊張、生死攸關的遭遇,演變為一段複雜而危險的浪漫關係。動態應從戲# 1. 概述 本文主要介绍如何基于 **Spring Boot 2.X** 版本,实现对 **Spring MVC** 接口的**全局**和**自定义**返回结果。 > 艿艿:本文对应在提供在 [lab-23](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23) 中。 # 2. 为什么需要统一返回结果 在基于 **Spring MVC** 提供 API 接口时,一般需要给接口一个统一的返回结果。例如说: - 成功的返回结果 - 失败的返回结果 一般来说,我们至少需要返回三个属性: - `code`:状态码。无论是否成功,必须返回。成功,返回成功的状态码;失败,返回失败的状态码。 - `msg`:提示信息。发生错误时,前端可以基于该消息进行提示。 - `data`:数据。成功时,返回的数据。 当然,实际项目在返回结果上,会定义更多的属性。例如说,胖友可以看看艿艿在 [yudao-cloud](https://github.com/YunaiV/onemall) 项目中,定义的 [CommonResult](https://github.com/YunaiV/onemall/blob/master/common/common-core/src/main/java/cn/iocoder/common/framework/vo/CommonResult.java) 类。 # 3. 如何实现统一返回结果 在 Spring MVC 中,可以使用 `@RestControllerAdvice` + 实现 ResponseBodyAdvice 接口,实现对返回结果的拦截。如此,我们就可以将返回结果,包装成统一的格式。 > 艿艿:如果胖友对 `@RestControllerAdvice` 注解不了解,可以看看 [《Spring Boot 实现各种参数校验,写得太好了,建议收藏!》](http://www.iocoder.cn/Fight/Parameter-verification-for-Spring-Boot-implementation/?self) 文章。 下面,我们开始本小节的示例。 ## 3.1 引入依赖 在 [`pom.xml`](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/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> <artifactId>lab-23</artifactId> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- 实现对 Spring MVC 的自动化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 方便等会写单元测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project> ``` 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。 ## 3.2 CommonResult 在 [`cn.iocoder.springboot.lab23.springmvc.vo`](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/vo) 包路径下,创建 [CommonResult](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/vo/CommonResult.java) 类,统一返回结果。代码如下: ``` // CommonResult.java public class CommonResult<T> { public static Integer CODE_SUCCESS = 0; /** * 错误码 */ private Integer code; /** * 错误提示 */ private String message; /** * 返回数据 */ private T data; /** * 将传入的 result 对象,转换成另外一个泛型结果的对象 * * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。 * * @param result 传入的 result 对象 * @param <T> 返回的泛型 * @return 新的 CommonResult 对象 */ public static <T> CommonResult<T> error(CommonResult<?> result) { return error(result.getCode(), result.getMessage()); } public static <T> CommonResult<T> error(Integer code, String message) { Assert.isTrue(!CODE_SUCCESS.equals(code), "code 必须是错误的!"); CommonResult<T> result = new CommonResult<>(); result.code = code; result.message = message; return result; } public static <T> CommonResult<T> success(T data) { CommonResult<T> result = new CommonResult<>(); result.code = CODE_SUCCESS; result.data = data; result.message = ""; return result; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } } ``` - 比较简单,胖友自己瞅瞅即可。 ## 3.3 GlobalResponseBodyHandler 在 [`cn.iocoder.springboot.lab23.springmvc.core.web`](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/core/web) 包路径下,创建 [GlobalResponseBodyHandler](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/core/web/GlobalResponseBodyHandler.java) 类,实现 Spring MVC 的全局返回结果。代码如下: ``` // GlobalResponseBodyHandler.java @RestControllerAdvice(basePackages = "cn.iocoder.springboot.lab23.springmvc.controller") public class GlobalResponseBodyHandler implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 如果已经是 CommonResult 类型,则直接返回 if (body instanceof CommonResult) { return body; } // 如果不是,则包装成 CommonResult 类型 return CommonResult.success(body); } } ``` - 在类上,添加了 `@RestControllerAdvice` 注解,并且设置了只拦截 `"cn.iocoder.springboot.lab23.springmvc.controller"` 包。这样,我们可以更精准的拦截到我们需要拦截的 Controller 的返回结果。 - 实现 `ResponseBodyAdvice` 接口,重写两个方法。 - `#supports(...)` 方法,返回 `true` 。表示拦截 Controller 所有 API 接口的返回结果。 - `#beforeBodyWrite(...)` 方法,当返回的结果不是 CommonResult 类型时,则包装成 CommonResult 类型。当然,也可能存在 Controller 的某个 API 接口,不希望返回结果被包装起来,则可以在该方法中,增加一些判断逻辑。 - 有一点要注意,如果 Controller 的 API 接口,返回的结果是 String 类型,会报如下错误: ``` java.lang.ClassCastException: cn.iocoder.springboot.lab23.springmvc.vo.CommonResult cannot be cast to java.lang.String ``` - 原因是,Controller 的 API 接口,返回 String 类型时,会使用 StringHttpMessageConverter 类进行转换。而它只能处理 String 类型的结果。所以,我们需要特殊处理下,将 CommonResult 转换成 String 类型。代码如下: ``` // GlobalResponseBodyHandler.java @RestControllerAdvice(basePackages = "cn.iocoder.springboot.lab23.springmvc.controller") public class GlobalResponseBodyHandler implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 如果已经是 CommonResult 类型,则直接返回 if (body instanceof CommonResult) { return body; } // 字符串,特殊处理 if (body instanceof String) { try { return objectMapper.writeValueAsString(CommonResult.success(body)); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } // 如果不是,则包装成 CommonResult 类型 return CommonResult.success(body); } } ``` - 通过注入 `com.fasterxml.jackson.databind.ObjectMapper` Bean 对象,将 CommonResult 序列化成 JSON 字符串返回。 ## 3.4 UserController 在 [`cn.iocoder.springboot.lab23.springmvc.controller`](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/controller) 包路径下,创建 [UserController](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/controller/UserController.java) 类,提供返回 JSON 和字符串的示例 API 接口。代码如下: ``` // UserController.java @RestController @RequestMapping("/users") public class UserController { @GetMapping("/get") public UserVO get() { return new UserVO().setId(1).setUsername("yudaoyuanma"); } @GetMapping("/get2") public CommonResult<UserVO> get2() { return CommonResult.success(new UserVO().setId(1).setUsername("yudaoyuanma")); } @GetMapping("/get3") public String get3() { return "yudaoyuanma"; } } ``` - 提供了三个 API 接口,分别返回 UserVO 对象、CommonResult 对象、字符串。 其中,UserVO 代码如下: ``` // UserVO.java public class UserVO { private Integer id; private String username; public Integer getId() { return id; } public UserVO setId(Integer id) { this.id = id; return this; } public String getUsername() { return username; } public UserVO setUsername(String username) { this.username = username; return this; } } ``` ## 3.5 Application 创建 [`Application.java`](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/Application.java) 类,配置 `@SpringBootApplication` 注解即可。代码如下: ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` ## 3.6 简单测试 执行 `Application#main(String[] args)` 方法,启动 Spring Boot 应用。 ① 访问 <http://127.0.0.1:8080/users/get> 接口,返回结果如下: ``` { "code": 0, "message": "", "data": { "id": 1, "username": "yudaoyuanma" } } ``` - 返回结果被包装成 CommonResult 对象。 ② 访问 <http://127.0.0.1:8080/users/get2> 接口,返回结果如下: ``` { "code": 0, "message": "", "data": { "id": 1, "username": "yudaoyuanma" } } ``` - 返回结果已经是 CommonResult 对象,所以不会被再次包装。 ③ 访问 <http://127.0.0.1:8080/users/get3> 接口,返回结果如下: ``` {"code":0,"message":"","data":"yudaoyuanma"} ``` - 返回结果被包装成 CommonResult 对象,并序列化成 JSON 字符串返回。 # 4. 如何自定义返回结果 在 [「3. 如何实现统一返回结果」](http://www.iocoder.cn/Spring-Boot/Spring-MVC-unified-return/#) 中,我们实现了全局的返回结果。但是,如果我们希望某个 Controller 的 API 接口,不进行包装,而是直接返回结果,该怎么办呢? 例如说,我们在 Controller 上添加了 Swagger 注解,会生成 Swagger 接口文档。如果我们将返回结果进行包装了,会导致 Swagger 无法解析,接口文档无法生成。 下面,我们开始本小节的示例。 ## 4.1 引入依赖 在 [`pom.xml`](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/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> <artifactId>lab-23</artifactId> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- 实现对 Spring MVC 的自动化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 方便等会写单元测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project> ``` 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。 ## 4.2 CommonResult 在 [`cn.iocoder.springboot.lab23.springmvc.vo`](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/vo) 包路径下,创建 [CommonResult](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/vo/CommonResult.java) 类,统一返回结果。代码和 [「3.2 CommonResult」](http://www.iocoder.cn/Spring-Boot/Spring-MVC-unified-return/#) 一致。 ## 4.3 GlobalResponseBodyHandler 在 [`cn.iocoder.springboot.lab23.springmvc.core.web`](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/core/web) 包路径下,创建 [GlobalResponseBodyHandler](https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-23/src/main/java/cn/iocoder/springboot/lab23/springmvc/core/web/GlobalResponseBodyHandler.java) 类,实现 Spring MVC 的全局返回结果。代码如下: ``` // GlobalResponseBodyHandler.java @RestControllerAdvice public class GlobalResponseBodyHandler implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter returnType, Class converterType) { if (returnType.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) { // 情况一,方法级别 return false; } if (returnType.getContainingClass().isAnnotationPresent(IgnoreResponseAdvice.class)) { // 情况二,类级别 return false; } return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 如果已经是 CommonResult 类型,则直接返回 if (body instanceof CommonResult) { return

數據

0對話數
0按讚
0追蹤者
Jacaerys

創作者

Jacaerys

與角色聊天 雷伊

開始聊天