当前位置: 首页>前端>正文

springboot中实现openai返回的连续输出 springboot返回map

在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量。那么SpringBoot如何做到统一的后端返回格式呢?今天我们一起来看看。

为什么要对SpringBoot返回统一的标准格式

在默认情况下,SpringBoot的返回格式常见的有三种:

返回String

1. @GetMapping("/hello")
2. publicString(){
3. return"hello";
4. }

此时调用接口获取到的返回值是这样:

hello

返回自定义对象

1. @GetMapping("/student")
2. publicStudent(){
3. Student=newStudent();
4. .setId(1);
5. .setName("didiplus");
6. return;
7. }
8.
9. //student的类
10. @Data
11. publicclassStudent{
12. privateInteger;
13. privateString;
14. }

此时调用接口获取到的返回值是这样:

{"id":1,"name":"didiplus"}

接口异常

1. @GetMapping("/error")
2.publicint(){
3. int=9/0;
4. return;
5. }

此时调用接口获取到的返回值是这样:

springboot中实现openai返回的连续输出 springboot返回map,springboot中实现openai返回的连续输出 springboot返回map_Data,第1张

SpringBoot的版本是v2.6.7,

定义返回对象

1. package.didiplus.common.web.respons
3. import.Data;
5. import.io.Serializable;
7. /**
8.  * Author: didiplus
9.  * Email: 972479352@qq.com
10.  * CreateTime: 2022/4/24
11.  * Desc: Ajax 返 回 JSON 结 果 封 装 数 据
12.  */
13. 
14. @Data
15. publicclassResult<T>implementsSerializable{
16. 
17. /**
18.      * 是否返回成功
19.      */
20. privateboolean;
21. 
22. /**
23.      * 错误状态
24.      */
25. privateint;
26. 
27. /***
28.      * 错误信息
29.      */
30. privateString;
31. 
32. /**
33.      * 返回数据
34.      */
35. private;
36. 
37. /**
38.      * 时间戳
39.      */
40. privatelong;
41. 
42. publicResult(){
43. this.timestamp =System.currentTimeMillis();
44. }
45. /**
46.      * 成功的操作
47.      */
48. publicstatic<T>Result<T>(){
49. return(null);
50. }
51. 
52. /**
53.      * 成 功 操 作 , 携 带 数 据
54.      */
55. publicstatic<T>Result<T>(T data){
56. return(ResultCode.RC100.getMessage(),data);
57. }
58. 
59. /**
60.      * 成 功 操 作, 携 带 消 息
61.      */
62. publicstatic<T>Result<T>(String){
63. return(message,null);
64. }
65. 
66. /**
67.          * 成 功 操 作, 携 带 消 息 和 携 带 数 据
68.          */
69. publicstatic<T>Result<T>(String,){
70. return(ResultCode.RC100.getCode(),,);
71. }
72. 
73. /**
74.      * 成 功 操 作, 携 带 自 定 义 状 态 码 和 消 息
75.      */
76. publicstatic<T>Result<T>(int,String){
77. return(code,,null)
78. }
79. 
80. publicstatic<T>Result<T>(int,String,T data){
81. Result<T>=newResult<T>();
82. .setCode(code);
83. .setMsg(message);
84. .setSuccess(true);
85. .setData(data);
86. return;
87. }
88. 
89. /**
90.      * 失 败 操 作, 默 认 数 据
91.      */
92. publicstatic<T>Result<T>(){
93. return(ResultCode.RC100.getMessage());
94. }
95. 
96. /**
97.      * 失 败 操 作, 携 带 自 定 义 消 息
98.      */
99. publicstatic<T>Result<T>(String){
100. return(message,null);
101. }
102. 
103. /**
104.      * 失 败 操 作, 携 带 自 定 义 消 息 和 数 据
105.      */
106. publicstatic<T>Result<T>(String,){
107. return(ResultCode.RC999.getCode(),,);
108. }
109. 
110. /**
111.      * 失 败 操 作, 携 带 自 定 义 状 态 码 和 自 定 义 消 息
112.      */
113. publicstatic<T>Result<T>(int,String){
114. return(ResultCode.RC999.getCode(),,null);
115. }
116. 
117. /**
118.      * 失 败 操 作, 携 带 自 定 义 状 态 码 , 消 息 和 数 据
119.      */
120. publicstatic<T>Result<T>(int,String,){
121. Result<T>=newResult<T>();
122. .setCode(code);
123. .setMsg(message);
124. .setSuccess(false);
125. .setData(data);
126. return;
127. }
128. 
129. /**
10.      * Boolean 返 回 操 作, 携 带 默 认 返 回 值
131.      */
132. publicstatic<T>Result<T>(boolean){
13. return(b,ResultCode.RC100.getMessage(),ResultCode.RC999.getMessage());
134. }
135. 
136. /**
137.      * Boolean 返 回 操 作, 携 带 自 定 义 消 息
138.      */
139. publicstatic<T>Result<T>(boolean,String,String){
140. if(b){
141
142. }else{
143. return(failure);
144. }
145. }
146. }

定义状态码

1. package.didiplus.common.web.response;
2. 
3. import.Getter;
4. 
5. /**
6.  * Author: didiplus
7.  * Email: 972479352@qq.com
8.  * CreateTime: 2022/4/24
9.  * Desc: 统 一 返 回 状 态 码
10.  */
11. publicenumResultCode{
12. /**操作成功**/
13. (100,"操作成功"),
14. /**操作失败**/
15. (999,"操作失败"),
16. /**服务限流**/
17. (200,"服务开启限流保护,请稍后再试!"),
18. /**服务降级**/
19. (201,"服务开启降级保护,请稍后再试!"),
20. /**热点参数限流**/
21. (202,"热点参数限流,请稍后再试!"),
22. /**系统规则不满足**/
23. (203,"系统规则不满足要求,请稍后再试!"),
24. /**授权规则不通过**/
25. (204,"授权规则不通过,请稍后再试!"),
26. /**access_denied**/
27. (403,"无访问权限,请联系管理员授予权限"),
28. /**access_denied**/
29. (401,"匿名用户访问无权限资源时的异常"),
30. /**服务异常**/
31. (500,"系统异常,请稍后重试"),
32. 
3
34. (2003,"没有权限访问该资源"),
35. (1001,"客户端认证失败"),
36. (1002,"用户名或密码错误"),
37. (1003,"不支持的认证模式");
38. 
39. /**自定义状态码**/
40. @Getter
41. privatefinalint;
42. 
43. /**
44.      * 携 带 消 息
45.      */
46. @Getter
47. privatefinalString;
48. /**
49.      * 构 造 方 法
50.      */
51. ResultCode(int,String){
52. 
53. this.code =;
54. 
55. this.message =;
56. }
57. }

统一返回格式

1. @GetMapping("/hello")
2. publicResult<String>(){
3. returnResult.success("操作成功","hello");
4. }

此时调用接口获取到的返回值是这样:

    1. {"success":true,"code":100,"msg":"操作成功","data":"hello","timestamp":1650785058049}

    这样确实已经实现了我们想要的结果,我在很多项目中看到的都是这种写法,在Controller层通过Result.success()对返回结果进行包装后返回给前端。这样显得不够专业而且不够优雅。 所以呢我们需要对代码进行优化,目标就是不要每个接口都手工制定Result返回值。

    高级实现方式

    要优化这段代码很简单,我们只需要借助SpringBoot提供的ResponseBodyAdvice即可。

    ResponseBodyAdvice的源码:

    只需要编写一个具体实现类即可

    1. publicinterfaceResponseBodyAdvice<T>{
    2. /**
    3. 		* 是否支持advice功能
    4. 		* true 支持,false 不支持
    5. 		*/
    6. boolean(MethodParameter,Class<?extendsHttpMessageConverter<?>>);
    7. 
    8. /**
    9. 		* 对返回的数据进行处理
    10. 		*/
    11. @Nullable
    12. (@Nullable,MethodParameter,MediaType,Class<?extendsHttpMessageConverter<?>>,ServerHttpRequest,ServerHttpResponse);
    13. }
    1. @RestControllerAdvice
    2. publicclassResponseAdviceimplementsResponseBodyAdvice<Object>{
    3. 
    4. @Autowired
    5. ObjectMapper;
    6. 
    7. @Override
    8. publicboolean(MethodParameter,Class<?extendsHttpMessageConverter<?>>){
    9. returntrue;
    10. }
    11. 
    12. @SneakyThrows
    13. @Override
    14. publicObject(Object,MethodParameter,MediaType,Class<?extendsHttpMessageConverter<?>>,ServerHttpRequest,ServerHttpResponse){
    15. if(body instanceofString){
    16. return.writeValueAsString(Result.success(ResultCode.RC100.getMessage(),body));
    17. }
    18. returnResult.success(ResultCode.RC100.getMessage(),body);
    19. }
    20. }

    需要注意两个地方:

    @RestControllerAdvice注解 @RestControllerAdvice是@RestController注解的增强,可以实现三个方面的功能:

    1. 全局异常处理
    2. 全局数据绑定
    3. 全局数据预处理

    String类型判断

    1. if(body instanceofString){
    2. return.writeValueAsString(Result.success(ResultCode.RC100.getMessage(),body));
    3. }

    这段代码一定要加,如果Controller直接返回String的话,SpringBoot是直接返回,故我们需要手动转换成json。 经过上面的处理我们就再也不需要通过ResultData.success()来进行转换了,直接返回原始数据格式,SpringBoot自动帮我们实现包装类的封装。

    1. @GetMapping("/hello")
    2. publicString(){
    3. return"hello,didiplus";
    4. }
    5.
    6. @GetMapping("/student")
    7. publicStudent(){
    8. Student=newStudent();
    9. .setId(1);
    10. .setName("didiplus");
    11. return;
    12. }

    此时我们调用接口返回的数据结果为:

      1. {
      2. "success":true,
      3. "code":100,
      4. "msg":"操作成功",
      5. "data":"hello,didiplus",
      6. "timestamp":1650786993454
      7. }


      https://www.xamrdz.com/web/2nw1951611.html

      相关文章: