springboot封装统一返回
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封装统一返回的更多相关文章
- (三)SpringBoot定义统一返回result对象
一:定义响应码枚举 package com.example.demo.core.ret; /** * @Description: 响应码枚举,参考HTTP状态码的语义 * @author * @dat ...
- 统一返回对象封装和统一异常捕获封装springboot starter
好久没有更新文章了,高龄开发没什么技术,去了外包公司后没怎么更新文章了.今天分享下统一处理starter,相信开发web系统的时候都是会涉及到前后端的交互,而后端返回数据的时候一般都会统一封装一个返回 ...
- springboot之全局处理统一返回
springboot之全局处理统一返回 简介 在REST风格的开发中,避免通常会告知前台返回是否成功以及状态码等信息.这里我们通常返回的时候做一次util的包装处理工作,如:Result类似的类,里面 ...
- SpringBoot异常处理统一封装我来做-使用篇
SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...
- SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!
大家好,我是飘渺. 今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常. 首先我们来看看为什么要返回统一的标准格式? 为什么要对Sp ...
- SpringBoot 如何统一后端返回格式
在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量.那么SpringBoot如何做到统一的后端返回格式呢?今天我们一起来看看. 为什么要对SpringBoot返回统一 ...
- springboot统一返回json数据格式并配置系统异常拦截
本文链接:https://blog.csdn.net/syystx/article/details/82870217通常进行前后端分离开发时我们需要定义统一的json数据交互格式并对系统未处理异常进行 ...
- Spring Boot API 统一返回格式封装
今天给大家带来的是Spring Boot API 统一返回格式封装,我们在做项目的时候API 接口返回是需要统一格式的,只有这样前端的同学才可对接口返回的数据做统一处理,也可以使前后端分离 模式的开发 ...
- Java封装接口统一返回数据模板
现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...
- spring boot 2 全局统一返回RESTful风格数据、统一异常处理
全局统一返回RESTful风格数据,主要是实现ResponseBodyAdvice接口的方法,对返回值在输出之前进行修改.使用注解@RestControllerAdvice拦截异常并统一处理. 开发环 ...
随机推荐
- 27、flutter Dialog 弹窗
AlertDialog //放在State<>之下 void _alertDialog() async { var result = await showDialog( barrierDi ...
- LeetCode 哈希表、映射、集合篇(242、49)
242. 有效的字母异位词 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = " ...
- 记一次 MySQL timestamp 精度问题的排查 → 过程有点曲折
开心一刻 下午正准备出门,跟正刷着手机的老妈打个招呼 我:妈,今晚我跟朋友在外面吃,就不在家吃了 老妈拿着手机跟我说道:你看这叫朋友骗缅北去了,tm血都抽干了,多危险 我:那是他不行,你看要是吴京去了 ...
- 华为云GaussDB城市沙龙活动走进安徽,助力金融行业数字化转型
本文分享自华为云社区<华为云GaussDB城市沙龙活动走进安徽,助力金融行业数字化转型>,作者: GaussDB 数据库 . 近日,华为云GaussDB数据库城市沙龙·安徽站圈层活动顺利举 ...
- GaussDB技术解读系列之SQL Audit,面向应用开发的SQL审核工具
本文分享自华为云社区<GaussDB技术解读系列之SQL Audit,面向应用开发的SQL审核工具>,作者:华为云数据库和应用迁移专家. 前言 我们先从一个SQL语句说起(以某传统 ...
- 聊聊数仓中TPCD-DS&TPC-H与查询性能的那些事儿
摘要:详细讲述使用GaussDB(DWS)时,如何使用TPC-DS/TPC-H等标准数据模型,获取DWS的查询性能数据. 本文分享自华为云社区<GaussDB(DWS) <DWS之TPCD ...
- storybook组件属性详解:组件props到strorybook Args
首先我们查看官方文档:https://storybook.js.org/docs/vue/writing-docs/doc-block-argstable#customizing 官方的例子么有看到v ...
- Cesium球心坐标与本地坐标系经纬转换的数学原理—矩阵变换
之前整理过:<透析矩阵,由浅入深娓娓道来-高数-线性代数-矩阵>.<三维旋转笔记:欧拉角/四元数/旋转矩阵/轴角-记忆点整理>,这次转载 FuckGIS的<Cesium之 ...
- 基于jdk自带httpserver开发的最小完整MVC框架
基于jdk自带httpserver开发的最小完整MVC框架 410kb级的完整MVC:solon(83k) + jdkhttp(27k) + enjoy(227k) + snack3(73k) DEM ...
- Solon 1.6.29 发布,轻量级应用开发框架
关于官网 千呼万唤始出来: https://solon.noear.org .整了一个月多了...还得不断接着整! 关于 Solon Solon 是一个轻量级应用开发框架.支持 Web.Data.Jo ...