个人博客开发之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

相关文章

Ubuntu中Nginx虚拟主机设置的项目实践

《Ubuntu中Nginx虚拟主机设置的项目实践》通过配置虚拟主机,可以在同一台服务器上运行多个独立的网站,本文主要介绍了Ubuntu中Nginx虚拟主机设置的项目实践,具有一定的参考价值,感兴趣的可... 目录简介安装 Nginx创建虚拟主机1. 创建网站目录2. 创建默认索引文件3. 配置 Nginx4

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

使用DeepSeek搭建个人知识库(在笔记本电脑上)

《使用DeepSeek搭建个人知识库(在笔记本电脑上)》本文介绍了如何在笔记本电脑上使用DeepSeek和开源工具搭建个人知识库,通过安装DeepSeek和RAGFlow,并使用CherryStudi... 目录部署环境软件清单安装DeepSeek安装Cherry Studio安装RAGFlow设置知识库总

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx