spring boot 统一JSON格式的接口返回结果的实现

下面我来详细讲解一下“Spring Boot 统一 JSON 格式的接口返回结果的实现”攻略。

1. 前言

在实际的项目中,我们往往需要为每个接口编写返回数据的格式,这样很浪费时间。而使用统一的 JSON 返回格式,不仅可以减少代码量,还能让前端开发更加便捷。本文将明确探讨在 Spring Boot 中如何实现这一目标。

2. 统一 JSON 格式的接口返回结果的实现

我们可以通过使用 Spring Boot 提供的拦截器、自定义注解、统一异常处理等来实现统一 JSON 格式的接口返回结果。下面分别介绍这三种方式的实现方法。

2.1 使用拦截器

我们可以通过编写拦截器,在接口调用完毕后修改返回的 JSON 格式。具体实现步骤如下:

  1. 创建一个拦截器类,实现 HandlerInterceptor 接口,并在 afterCompletion 方法中对返回结果进行处理,将其封装成统一 JSON 格式。

```java
@Component
public class ResponseHandlerInterceptor implements HandlerInterceptor {

   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                               Exception ex) throws Exception {
       if (ex != null) {
           // 异常不处理
           return;
       }
       if (handler instanceof HandlerMethod) {
           HandlerMethod handlerMethod = (HandlerMethod) handler;
           // 获取方法上的注解
           ApiResult apiResult = handlerMethod.getMethod().getAnnotation(ApiResult.class);

           if (apiResult != null) {
               // 获取返回值的类型
               Class<?> returnType = handlerMethod.getReturnType().getParameterType();
               // 判断是否是统一返回格式要求的类型
               if (!ApiResultVO.class.isAssignableFrom(returnType)) {
                   return;
               }
               // 强制类型转换
               ApiResultVO<Object> apiResultVO = (ApiResultVO<Object>) response.getBody();
               // 重新封装
               JsonResult<Object> jsonResult = new JsonResult<>();
               jsonResult.setCode(apiResultVO.getCode());
               jsonResult.setData(apiResultVO.getData());
               jsonResult.setMsg(apiResultVO.getMsg());
               response.setContentType(MediaType.APPLICATION_JSON_VALUE);
               response.setCharacterEncoding(StandardCharsets.UTF_8.name());
               response.getWriter().write(JsonUtils.toJson(jsonResult));
           }
       }
   }

}
```

  1. 创建一个注解 ApiResult,标记需要统一 JSON 格式返回结果的方法。

java
/**
* ApiResult 注解,标记需要统一 JSON 格式返回结果的方法
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiResult {
}

  1. 注册拦截器,放行操作

```java
@Configuration
public class ResponseHandlerConfig implements WebMvcConfigurer {

   @Autowired
   private ResponseHandlerInterceptor responseHandlerInterceptor;

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(responseHandlerInterceptor).addPathPatterns("/**");
   }

   @Override
   public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**")
               .allowedOrigins("*")
               .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
               .allowCredentials(false).maxAge(3600);
   }

}
```

  1. 在需要统一 JSON 格式返回结果的方法上加上 @ApiResult 注解即可。

java
/**
* 测试需要统一 JSON 格式返回结果的方法
* @return 返回 JSON 格式的数据
*/
@ApiResult
@GetMapping("/testJson")
public ApiResultVO<String> testJson() {
return ApiResultVO.success("测试成功");
}

2.2 使用自定义注解

我们可以通过自定义注解来实现简化操作。具体实现步骤如下:

  1. 创建一个注解 JsonResultFormat,标记需要统一 JSON 格式返回结果的类或方法。

java
/**
* JsonResultFormat 注解,标记需要统一 JSON 格式返回结果的类或方法
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonResultFormat {
}

  1. 创建一个拦截器类 JsonResultInterceptor,在接口调用完毕后修改返回的 JSON 格式。

```java
@Component
public class JsonResultInterceptor implements HandlerInterceptor {

   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                               Exception ex) throws Exception {
       if (ex != null) {
           // 异常不处理
           return;
       }

       if (handler instanceof HandlerMethod) {
           HandlerMethod handlerMethod = (HandlerMethod) handler;
           Class<?> beanType = handlerMethod.getBeanType();
           JsonResultFormat jsonResultFormat = beanType.getAnnotation(JsonResultFormat.class);
           if (jsonResultFormat == null) {
               jsonResultFormat = handlerMethod.getMethodAnnotation(JsonResultFormat.class);
           }

           if (jsonResultFormat != null) {
               // 获取返回值的类型
               Class<?> returnType = handlerMethod.getReturnType().getParameterType();
               // 判断是否是统一返回格式要求的类型
               if (!ApiResultVO.class.isAssignableFrom(returnType)) {
                   return;
               }
               // 强制类型转换
               ApiResultVO<Object> apiResultVO = (ApiResultVO<Object>) response.getBody();
               // 重新封装
               JsonResult<Object> jsonResult = new JsonResult<>();
               jsonResult.setCode(apiResultVO.getCode());
               jsonResult.setData(apiResultVO.getData());
               jsonResult.setMsg(apiResultVO.getMsg());
               response.setContentType(MediaType.APPLICATION_JSON_VALUE);
               response.setCharacterEncoding(StandardCharsets.UTF_8.name());
               response.getWriter().write(JsonUtils.toJson(jsonResult));
           }
       }
   }

}
```

  1. 注册拦截器

```java
@Configuration
public class JsonResultInterceptorConfig implements WebMvcConfigurer {

   @Autowired
   private JsonResultInterceptor jsonResultInterceptor;

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(jsonResultInterceptor).addPathPatterns("/**");
   }

   @Override
   public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**")
               .allowedOrigins("*")
               .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
               .allowCredentials(false).maxAge(3600);
   }

}
```

  1. 在需要统一 JSON 格式返回结果的方法上加上 @JsonResultFormat 注解即可。

java
/**
* 测试需要统一 JSON 格式返回结果的方法
* @return 返回 JSON 格式的数据
*/
@JsonResultFormat
@GetMapping("/testJson")
public ApiResultVO<String> testJson() {
return ApiResultVO.success("测试成功");
}

2.3 统一异常处理

在项目中,统一异常处理也是非常重要的,我们可以在统一异常处理时,将异常信息封装成统一的 JSON 格式返回给前端。

首先,我们需要自定义一个异常类 JsonException,继承 RuntimeException,并添加需要的属性。

/**
* 统一 JSON 格式异常类
*/
public class JsonException extends RuntimeException {

   /**
    * 状态码
    */
   private Integer code;

   /**
    * 返回消息
    */
   private String msg;

   /**
    * 异常信息
    */
   private String errorMsg;

   /**
    * 构造函数
    * @param code 状态码
    * @param msg 状态消息
    * @param errorMsg 异常信息
    */
   public JsonException(Integer code, String msg, String errorMsg) {
       this.code = code;
       this.msg = msg;
       this.errorMsg = errorMsg;
   }

   public Integer getCode() {
       return code;
   }

   public void setCode(Integer code) {
       this.code = code;
   }

   public String getMsg() {
       return msg;
   }

   public void setMsg(String msg) {
       this.msg = msg;
   }

   public String getErrorMsg() {
       return errorMsg;
   }

   public void setErrorMsg(String errorMsg) {
       this.errorMsg = errorMsg;
   }
}

然后,我们需要自定义一个异常处理器 JsonExceptionHandler,捕获操作过程中可能出现的异常,并将其封装成统一的 JSON 格式返回前端。

@ControllerAdvice
public class JsonExceptionHandler {

   /**
    * 处理业务异常
    * @param e 业务异常
    * @param request 请求体
    * @return JSON 格式结果
    */
   @ExceptionHandler(value = JsonException.class)
   @ResponseBody
   public JsonResult<String> jsonExceptionHandler(JsonException e, HttpServletRequest request) {
       log.error("请求地址:[{}],错误信息:[{}]", request.getRequestURL(), e.getErrorMsg());
       JsonResult<String> result = new JsonResult<>();
       result.setCode(e.getCode());
       result.setMsg(e.getMsg());
       return result;
   }

   /**
    * 处理空指针异常
    * @param e 空指针异常
    * @param request 请求体
    * @return JSON 格式结果
    */
   @ExceptionHandler(value = NullPointerException.class)
   @ResponseBody
   public JsonResult<String> nullPointerExceptionHandler(NullPointerException e, HttpServletRequest request) {
       log.error("请求地址:[{}],错误信息:[{}]", request.getRequestURL(), e.getMessage());
       JsonResult<String> result = new JsonResult<>();
       result.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
       result.setMsg("系统繁忙,请稍后重试");
       return result;
   }

   /**
    * 处理其他错误异常
    * @param e 异常
    * @param request 请求体
    * @return JSON 格式结果
    */
   @ExceptionHandler(value = Exception.class)
   @ResponseBody
   public JsonResult<String> exceptionHandler(Exception e, HttpServletRequest request) {
       log.error("请求地址:[{}],错误信息:[{}]", request.getRequestURL(), e.getMessage());
       JsonResult<String> result = new JsonResult<>();
       result.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
       result.setMsg("系统繁忙,请稍后重试");
       return result;
   }

最后需要注意的是,在 ApiResultVOJsonResult 中,code 字段用于标记接口状态码,一般正常情况下为 0,而 msg 字段用于返回处理结果描述信息,data 字段返回数据内容。

3. 总结

本文介绍了三种实现统一 JSON 格式的接口返回结果的方法,分别是使用拦截器、自定义注解和统一异常处理。通过实现统一的返回格式,可以减少代码量,提升开发效率。同时,通过统一异常处理的方式,还可以将错误信息封装成统一 JSON 格式返回给前端,便于前端程序员查看和处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring boot 统一JSON格式的接口返回结果的实现 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java Spring Boot实战练习之单元测试篇

    以下是”Java Spring Boot实战练习之单元测试篇”的完整攻略,包含了步骤和示例。 1. 什么是单元测试 单元测试是一种测试方法,它用于测试整个系统或应用程序的一个单独模块或方法。单元测试是一种自动化测试方法,它能够验证代码、避免错误和缺陷,并将问题隔离到特定的代码块层面上。 2. 创建一个Spring Boot项目 在开始单元测试之前,需要先创建…

    Java 2023年5月19日
    00
  • Java之Jackson的基本使用案例讲解

    Java之Jackson的基本使用案例讲解 什么是Jackson Jackson是一个基于Java开发的JSON处理工具,它可以将Java对象转换成JSON格式的数据,并且可以将JSON格式的数据转换成Java对象。它的优势在于轻量级、性能卓越、使用简单等特点,因此在Java开发中十分常用。 Jackson的基本用法 1. 导入Jackson依赖 在使用Ja…

    Java 2023年5月26日
    00
  • Java中Mybatis,SpringMVC,Spring的介绍及联系

    以下是关于“Java中Mybatis,SpringMVC,Spring的介绍及联系”的完整攻略,其中包含两个示例。 1. 前言 Java中的Mybatis、SpringMVC和Spring是三个常用的开发框架,它们各自有不同的作用和特点,但也有联系和互相依赖的地方。本攻略将详细介绍Mybatis、SpringMVC和Spring的作用、特点以及联系。 2. …

    Java 2023年5月16日
    00
  • 详解如何使用MyBatis简化JDBC开发

    下面我给您详细讲解如何使用MyBatis简化JDBC开发的完整攻略。 什么是MyBatis? MyBatis是一款优秀的Java持久层框架,可以对JDBC进行封装,使得我们在开发过程中不再需要手动编写JDBC的相关代码,极大地简化了代码编写的难度,并提高了开发效率。 如何使用MyBatis? 添加依赖 使用Maven构建项目时,在pom.xml文件中加入以下…

    Java 2023年5月20日
    00
  • Python自定义计算时间过滤器实现过程解析

    我来为你讲解一下“Python自定义计算时间过滤器实现过程解析”的完整攻略。 简介 在Python中,我们可以使用过滤器来过滤一些特定的数据,比如时间过滤器。但是在一些特殊的情况下,现有的时间过滤器可能无法满足我们的需求,这时我们就需要自定义一个时间过滤器。 本文将介绍如何在Python中自定义一个计算时间的过滤器,以及如何在Django项目中使用这个自定义…

    Java 2023年5月26日
    00
  • Spring Boot 配置和使用多线程池的实现

    下面是关于Spring Boot配置和使用多线程池的实现的完整攻略。 概述 Spring Boot是一个开源的JavaEE(现在改名为Jakarta EE)快速开发框架,由于其快速开发和开箱即用的特性,受到了广泛的欢迎。在Spring Boot中,我们可以非常容易地配置和使用多线程池。使用多线程池可以显著提高应用程序的性能,特别是在处理IO密集型任务时。 添…

    Java 2023年5月19日
    00
  • Fluent Mybatis,原生Mybatis,Mybatis Plus三者功能对比

    针对“Fluent Mybatis,原生Mybatis,Mybatis Plus三者功能对比”的比较和讲解,以下是详细的攻略。 一、三者介绍 1. 原生Mybatis 原生Mybatis就是指在没有任何封装、框架的情况下使用Mybatis。通过编写SQL语句、映射文件和Java代码等相关文件来实现对数据库的操作。 2. Mybatis Plus Mybati…

    Java 2023年5月20日
    00
  • Springboot整合JwtHelper实现非对称加密

    下面是关于SpringBoot整合JwtHelper实现非对称加密的攻略: 一、背景知识 在了解攻略之前,需要先了解以下一些背景知识: JwtHelper:一个用于生成和验证JSON Web Tokens的Java库; 非对称加密算法:使用公钥和私钥加密、解密数据的算法,具有数据安全、数据完整性验证等优点。 本攻略将会使用JwtHelper库结合RSA非对称…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部