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

2024-06-16 14:38

本文主要是介绍个人博客开发之blog-api项目统一结果集api封装,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

由于返回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封装的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066715

相关文章

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

在IntelliJ IDEA中高效运行与调试Spring Boot项目的实战步骤

《在IntelliJIDEA中高效运行与调试SpringBoot项目的实战步骤》本章详解SpringBoot项目导入IntelliJIDEA的流程,教授运行与调试技巧,包括断点设置与变量查看,奠定... 目录引言:为良驹配上好鞍一、为何选择IntelliJ IDEA?二、实战:导入并运行你的第一个项目步骤1

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文