前言

由于返回json api 格式接口,所以我们需要通过java bean封装一个统一数据返回格式,便于和前端约定交互,

状态码枚举ResultCode

package cn.soboys.core.ret;import lombok.Getter;/*** @author kenx* @version 1.0* @date 2021/6/17 15:35* 响应码枚举,对应HTTP状态码*/
@Getter
public enum ResultCode {SUCCESS(200, "成功"),//成功//FAIL(400, "失败"),//失败BAD_REQUEST(400, "Bad Request"),UNAUTHORIZED(401, "认证失败"),//未认证NOT_FOUND(404, "接口不存在"),//接口不存在INTERNAL_SERVER_ERROR(500, "系统繁忙"),//服务器内部错误METHOD_NOT_ALLOWED(405,"方法不被允许"),/*参数错误:1001-1999*/PARAMS_IS_INVALID(1001, "参数无效"),PARAMS_IS_BLANK(1002, "参数为空");/*用户错误2001-2999*/private Integer code;private String message;ResultCode(int code, String message) {this.code = code;this.message = message;}
}

结果体Result

package cn.soboys.core.ret;import lombok.Data;import java.io.Serializable;/*** @author kenx* @version 1.0* @date 2021/6/17 15:47* 统一API响应结果格式封装*/
@Data
public class Result<T> implements Serializable {private static final long serialVersionUID = 6308315887056661996L;private Integer code;private String message;private T data;public Result setResult(ResultCode resultCode) {this.code = resultCode.getCode();this.message = resultCode.getMessage();return this;}public Result setResult(ResultCode resultCode, T data) {this.code = resultCode.getCode();this.message = resultCode.getMessage();this.setData(data);return this;}}

响应结果方法工具类

package cn.soboys.core.ret;/*** @author kenx* @version 1.0* @date 2021/6/17 16:30* 响应结果返回封装*/
public class ResultResponse {private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";// 只返回状态public static Result success() {return new Result().setResult(ResultCode.SUCCESS);}// 成功返回数据public static Result success(Object data) {return new Result().setResult(ResultCode.SUCCESS, data);}// 失败public static Result failure(ResultCode resultCode) {return new Result().setResult(resultCode);}// 失败public static Result failure(ResultCode resultCode, Object data) {return new Result().setResult(resultCode, data);}}

自定义解析controller拦截

注解@ResponseResult

package cn.soboys.core.ret;import java.lang.annotation.*;/*** @author kenx* @version 1.0* @date 2021/6/17 16:43* 统一包装接口返回的值 Result*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseResult {}

请求拦截ResponseResultInterceptor

package cn.soboys.core.ret;import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;/*** @author kenx* @version 1.0* @date 2021/6/17 17:10* 请求拦截*/
public class ResponseResultInterceptor implements HandlerInterceptor {//标记名称public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//请求方法if (handler instanceof HandlerMethod) {final HandlerMethod handlerMethod = (HandlerMethod) handler;final Class<?> clazz = handlerMethod.getBeanType();final Method method = handlerMethod.getMethod();//判断是否在对象上加了注解if (clazz.isAnnotationPresent(ResponseResult.class)) {//设置此请求返回体需要包装,往下传递,在ResponseBodyAdvice接口进行判断request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));//方法体上是否有注解} else if (method.isAnnotationPresent(ResponseResult.class)) {//设置此请求返回体需要包装,往下传递,在ResponseBodyAdvice接口进行判断request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));}}return true;}
}

请求全局解析ResponseResultHandler

package cn.soboys.core.ret;import cn.soboys.core.utils.HttpContextUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import javax.servlet.http.HttpServletRequest;/*** @author kenx* @version 1.0* @date 2021/6/17 16:47* 全局统一响应返回体处理*/
@Slf4j
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";/*** @param methodParameter* @param aClass* @return 此处如果返回false , 则不执行当前Advice的业务* 是否请求包含了包装注解 标记,没有直接返回不需要重写返回体,*/@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {HttpServletRequest request = HttpContextUtil.getRequest();//判断请求是否有包装标志ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANN);return responseResultAnn == null ? false : true;}/*** @param body* @param methodParameter* @param mediaType* @param aClass* @param serverHttpRequest* @param serverHttpResponse* @return 处理响应的具体业务方法*/@Overridepublic Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {if (body instanceof Result) {return body;} else if (body instanceof String) {return JSON.toJSONString(ResultResponse.success(body));} else {return ResultResponse.success(body);}}
}

具体详细内容请参考我这篇文章Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

关注公众号猿小叔获取更多干货分享

个人博客开发之blog-api项目统一结果集api封装相关推荐

  1. 博客搬迁至网易博客 http://happyboy200032.blog.163.com

    博客搬迁至网易博客 http://happyboy200032.blog.163.com 转载于:https://www.cnblogs.com/berryz2007/archive/2011/12/ ...

  2. 我的博客 http://aofengblog.blog.163.com/

    我的博客 http://aofengblog.blog.163.com/ ,内容:Java, Web, Linux, C, C++, Python, 数据库. 很高兴和大家交流.分享!

  3. SpringBoot 博客开发 个人学习(项目开始和前端页面)

    博客开发 前言 1.需求与功能 1.1 需求 1.2 功能 2.页面开发(非重点,可直接跳过看后台部分) ===>>前端展示页面 2.1 首页 2.2 详情页 2.3 分类页 2.4 标签 ...

  4. Jekyll 教程——博客功能(blog)

    相信很多程序员选择 Jekyll 是为了搭建个人博客,虽然它远不止于此.本篇我们就来介绍 Jekyll 的博客功能. 博客文件约定 当一个全新的 Jekyll 项目创建完成时,默认会生成一个 _pos ...

  5. 博客开张+第1个项目:云云图书馆

    我是编程业余爱好者,工作是中学里面的档案管理员.除了大学学过C++,我的工作跟编程没什么关系,但因为管理电子档案,所以跟excel打交道还是挺多的. 今年3月,我被小姐妹安利了在风变学python,于 ...

  6. Android 程序员不得不收藏的 90+ 个人博客(持续更新,android项目实战手机安全卫士

    来自滴滴出行,Android 开发助手 开发者,android-open-project 维护者 ,android-open-project-analysis 维护者. 中二病也要开发 ANDROID ...

  7. 菜鸡博客开……开……开源了!

    因为很多人找我要过博皮源码,所以本宝宝经过深思熟虑,最终决定把自己的源码分享给大家! 不过! 我肯定不会直接给CSS+页首页脚html的,毕竟弄一个一毛一样的博客就真心没意思了. 所以我把自己的代码分 ...

  8. java 博客系统_讲解开源项目:5分钟搭建私人Java博客系统

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行 Tale 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出的< ...

  9. Diango博客--19.使用 Docker部署项目到线上服务器

    文章目录 1.克隆代码到服务器 2.创建环境变量文件用于存放项目敏感信息 3.在 .production 文件写入下面的内容并保存 4.修改 Nginx 配置 5.修改项目配置文件 6.启动容器 7. ...

最新文章

  1. 轻量级的jQuery表单验证插件 - HAPPY.js
  2. golang channel 管道
  3. es配置中防止脑裂的配置
  4. MongoDB数据库的下载与Python交互
  5. 前缀 中缀 后缀表达式
  6. 每天一道LeetCode-----计算给定范围内所有数的与运算结果
  7. oracle消耗内存的查询,在AIX中计算ORACLE消耗的私有内存总数
  8. 最少步数(信息学奥赛一本通-T1330)
  9. 浅谈三层架构 通过这个,+Java开发模式经验。终于相通了,动软到底是为什么这么做...
  10. Java应用中使用ShutdownHook友好地清理现场
  11. Delphi 法简介
  12. 单片机毕设选题 - stm32心率脉搏血压体征监测手表(嵌入式 物联网)
  13. Cocoa Touch基础
  14. btrfs filesystem 增加容量
  15. Nginx之web前言
  16. main()的使用说明 (一叶知秋)
  17. r语言 转录本结构及丰度_桑基图的绘制核心微生物组分类学及丰度展示
  18. Ansible 部署的时候提示错误 SSH password instead
  19. 技巧:Vimdiff 使用
  20. scrapy配置user-agent中间件和ip代理中间件

热门文章

  1. WiFi基础学习到实战(三:WiFi网络“物理层”)
  2. 泽塔云在2022年Gartner中国区超融合市场竞争报告中被评为优秀厂商代表
  3. 怎么用手机记笔记?安卓手机超实用的笔记app
  4. [系统安全] 虚拟化安全之虚拟化概述
  5. Fiddler-使用教程
  6. 30岁的女程序员该何去何从
  7. 大数据里面说的“移动计算比移动数据划算”究竟是什么意思
  8. to_Date()用法
  9. Qt 圆形进度条实现
  10. 职业规划,如何月入1万、3万、5万、10万?