springboot返回统一的标准格式

定义注解

package com.yaoling.annotation;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseResult { }

controller层引入注解

@RestController
@RequestMapping(value = "/material/api/v1/laboratoryWarehouse/")
@ResponseResult //引入注解
public class LaboratoryWarehouseController {
....

统一返回Response类编写

枚举类

public enum ResultCode  {
SUCCESS(200, "成功"),
FAILED(500, "失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限"); private int code;
private String message; ResultCode(int code,String message) {
this.code = code;
this.message = message;
} public int getCode() {
return code;
} public String getMessage() {
return message;
}
}

返回类

@Data
public class Response<T> {
private int code;
private String description;
private T result;
private String expandMsg; public Response(int code, String description, T data) {
this.code = code;
this.description = description;
this.result = data;
} public static <T> Response<T> success(String description) {
return new Response<T>(ResultCode.SUCCESS.getCode(), description, null);
} public static <T> Response<T> success(T data) {
return new Response<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
} public static <T> Response<T> success(T data, String description) {
return new Response<T>(ResultCode.SUCCESS.getCode(), description, data);
} public static <T> Response<T> forbidden(T data) {
return new Response<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
} public static <T> Response<T> error(T data) {
return new Response<T>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMessage(), data);
} public static <T> Response<T> error(String description) {
return new Response<T>(ResultCode.FAILED.getCode(), description, null);
} public static <T> Response<T> error(String description, T data) {
return new Response<T>(ResultCode.FAILED.getCode(), description, data);
}
}

定义拦截器

执行链组件

@Component
public class ResponseResultInterceptor implements HandlerInterceptor { public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN"; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
Class<?> beanType = ((HandlerMethod) handler).getBeanType();
Method method = ((HandlerMethod) handler).getMethod(); //方法或class上有ResponseResult注解的,request设置属性
if (beanType.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, beanType.getAnnotation(ResponseResult.class));
} else if (method.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, method.getAnnotation(ResponseResult.class));
} }
return true;
} }

自定义拦截器

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
ResponseResultInterceptor interceptor = new ResponseResultInterceptor();
registry.addInterceptor(interceptor);
WebMvcConfigurer.super.addInterceptors(registry);
}
}

定义controller切面

@ControllerAdvice
public class ResponseResultHandler<T> implements ResponseBodyAdvice<Object> {
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN"; @Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra == null) {
return false;
}
//判断是否有RESPONSE_RESULT_ANN属性==>判断是否有引入ResponseResult注解
HttpServletRequest sraRequest = sra.getRequest();
ResponseResult responseResult = (ResponseResult) sraRequest.getAttribute(RESPONSE_RESULT_ANN);
return responseResult != null;
} @SneakyThrows
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
//返回body中有页码
if (body instanceof PageInfoVo) {
List<T> data = (List<T>) ((PageInfoVo<T>) body).getData();
int size = data.size(); //list中有数据
if (size > 0) {
ObjectMapper objectMapper = new ObjectMapper();
List<Object> snakeList = new ArrayList<>(size); for (T datum : data) {
//object转JsonNode
JsonNode jsonNode = objectMapper.readTree(objectMapper.writeValueAsString(datum));
//JsonNode的key转为蛇形
JsonNode snakeJsonNode = JsonUtils.convertKeysToSnake(jsonNode); snakeList.add(snakeJsonNode);
} ((PageInfoVo<T>) body).setData((List<? extends T>) snakeList);
} return Response.success(body);
} //判断返回的body数据
if (body instanceof Response) {
return body;
} else if (body instanceof String) {
return Response.success(body);
}
return Response.success(body);
}
}

测试

接口

public class LaboratoryWarehouseController {
@Autowired
private LaboratoryWarehouseService service; @RequestMapping(method = RequestMethod.GET, value = "query")
public PageInfoVo<BaseMaterVo> query(@RequestBody BaseMaterialDto baseMaterialDto) {
//此时的返回类型为PageInfoVo<BaseMaterVo>
return service.query(baseMaterialDto);
}
}

接口结果

{
"code": 200,
"description": "成功",
"result": {
"pagination": {
"total": 1,
"totalPage": 1,
"page": 1,
"pageSize": 20
},
"data": [
{
"id": "573024997631591394",
"name": "环辛烷",
"code": "WL0028958",
"batch_no": "20231206-001",
"laboratory": null,
"preparation_date": null,
"warehouse_entry_time": "2023-12-06 00:00:00"
}
]
},
"expandMsg": null
}

springboot封装统一返回的更多相关文章

  1. (三)SpringBoot定义统一返回result对象

    一:定义响应码枚举 package com.example.demo.core.ret; /** * @Description: 响应码枚举,参考HTTP状态码的语义 * @author * @dat ...

  2. 统一返回对象封装和统一异常捕获封装springboot starter

    好久没有更新文章了,高龄开发没什么技术,去了外包公司后没怎么更新文章了.今天分享下统一处理starter,相信开发web系统的时候都是会涉及到前后端的交互,而后端返回数据的时候一般都会统一封装一个返回 ...

  3. springboot之全局处理统一返回

    springboot之全局处理统一返回 简介 在REST风格的开发中,避免通常会告知前台返回是否成功以及状态码等信息.这里我们通常返回的时候做一次util的包装处理工作,如:Result类似的类,里面 ...

  4. SpringBoot异常处理统一封装我来做-使用篇

    SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...

  5. SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!

    大家好,我是飘渺. 今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常. 首先我们来看看为什么要返回统一的标准格式? 为什么要对Sp ...

  6. SpringBoot 如何统一后端返回格式

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

  7. springboot统一返回json数据格式并配置系统异常拦截

    本文链接:https://blog.csdn.net/syystx/article/details/82870217通常进行前后端分离开发时我们需要定义统一的json数据交互格式并对系统未处理异常进行 ...

  8. Spring Boot API 统一返回格式封装

    今天给大家带来的是Spring Boot API 统一返回格式封装,我们在做项目的时候API 接口返回是需要统一格式的,只有这样前端的同学才可对接口返回的数据做统一处理,也可以使前后端分离 模式的开发 ...

  9. Java封装接口统一返回数据模板

    现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...

  10. spring boot 2 全局统一返回RESTful风格数据、统一异常处理

    全局统一返回RESTful风格数据,主要是实现ResponseBodyAdvice接口的方法,对返回值在输出之前进行修改.使用注解@RestControllerAdvice拦截异常并统一处理. 开发环 ...

随机推荐

  1. ElasticSearch之Clone index API

    使用已有的索引,复制得到一个索引. 关闭testindex_001的写入操作,命令样例如下: curl -X PUT "https://localhost:9200/testindex_00 ...

  2. 痞子衡嵌入式:在i.MXRT1170上快速点亮一款全新LCD屏的方法与步骤(MIPI DSI接口)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在i.MXRT1170上快速点亮一款全新LCD屏的方法与步骤. 我们知道 LCD 屏的接口有很多:DPI-RGB.MIPI DSI.DB ...

  3. 欧拉定理 & 扩展欧拉定理 笔记

    欧拉函数 欧拉函数定义为:\(\varphi(n)\) 表示 \(1 \sim n\) 中所有与 \(n\) 互质的数的个数. 关于欧拉函数有下面的性质和用途: 欧拉函数是积性函数.可以通过这个性质求 ...

  4. Windows环境下为Android编译OpenCV4.3

    Windows环境下为Android编译OpenCV4.3 踩了三四天的坑,今天终于顺利跑通了,原来是toolchain的问题,外网的教程大多都是用opencv source里的toolchain,会 ...

  5. C#/.NET学习值得推荐的在线论坛和技术社区

    前言 本文来源于知乎的一个提问,C#/.NET程序员学习有哪些值得推荐的在线论坛和技术社区?其实很早之前DotNetGuide就已经新增了C#/.NET/.NET Core充电站栏目,当然大家有更好的 ...

  6. BeanDefinition解密:构建和管理Spring Beans的基石

    本文分享自华为云社区<Spring高手之路11--BeanDefinition解密:构建和管理Spring Beans的基石>,作者: 砖业洋__ . BeanDefinition是Spr ...

  7. 从零开始学python | 使用Python映射,过滤和缩减函数:所有您需要知道的

    摘要:在本文中,您将学习Python中的三个令人印象深刻的函数,即map(),filter和reduce(). Python提供了许多预定义的内置函数,最终用户可以通过调用它们来使用它们.这些功能不仅 ...

  8. PLS-00103: 出现符号 ")"在需要下列之一时

    执行 Oracle 存储过程时,出现 "PLS-00103: 出现符号 ")"在需要下列之一时:", Cause: java.sql.SQLException: ...

  9. SpringBoot 自定义初始化任务 Runner

    在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.可以通过实现Runner接口完成以上工作. 两者只是参数上的区别 方式一 实现 CommandLineRunner 接口 ...

  10. C# CRC8

    C# CRC8 C# /// /// This enum is used to indicate what kind of checksum you will be calculating. /// ...