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日

相关文章

  • 详解JDBC使用

    详解JDBC使用 什么是JDBC? Java Database Connectivity(JDBC)是Java编程语言用于执行与关系数据库的连接和访问的标准API。 JDBC的使用步骤 JDBC的使用步骤通常为以下5步: 加载JDBC驱动程序 创建数据库连接 创建Statement对象 执行SQL语句 处理结果 下面将会逐一讲解这5个步骤。 1. 加载JDB…

    Java 2023年6月15日
    00
  • Java小白第一次就能看懂的网络编程

    Java小白第一次就能看懂的网络编程攻略 什么是网络编程 网络编程指的是利用计算机网络进行通讯和信息交换的程序设计。Java中的网络编程是通过Java自带的网络库进行开发。 Java中的网络编程有两种:基于TCP协议的Socket编程和基于UDP协议的DatagramSocket编程。 Socket编程 Socket编程是指采用TCP协议来进行编程,是一个基…

    Java 2023年5月23日
    00
  • java 排序算法之归并排序

    Java 排序算法之归并排序 算法简介 归并排序(Merge Sort)是一种基于分治思想的排序算法,其基本思想是将待排序的序列不断列表分割为子序列,直到每个子序列只有一个元素,然后将子序列两两合并并按照考虑的比较规则合并成一个有序的大序列,直到最后整个序列有序。 归并排序的时间复杂度为O(nlogn),稳定排序,但是需要额外的空间复杂度O(n),因为需要额…

    Java 2023年5月19日
    00
  • Spring中BeanFactory和ApplicationContext的作用和区别(推荐)

    BeanFactory和ApplicationContext的区别 BeanFactory是Spring Framework中最基础的IOC容器,用于创建和管理应用中的Bean对象,提供对依赖注入(DI)和面向切面编程(AOP)的基本支持。 ApplicationContext是一个高级的IOC容器,它扩展了BeanFactory,并提供了更多的企业级功能,…

    Java 2023年5月19日
    00
  • 如何使用对象终结器?

    当对象的生命周期结束时,需要清理一些资源,如关闭文件、释放内存等。在C#中,可以使用对象终结器(finalizer)来实现删除对象之前清理所有相关资源的操作。本文将详细讲解如何使用对象终结器。 什么是对象终结器? 对象终结器是.NET框架提供的一种方法,用于确保对象的资源在对象生命周期结束时被释放。通常情况下,框架会自动进行垃圾回收,但是在某些情况下,需要手…

    Java 2023年5月11日
    00
  • jsp中include指令静态导入和动态导入的区别详解

    JSP中include指令静态导入和动态导入的区别详解 在JSP中,我们可以使用include指令来包含其他的页面。include指令有两种导入方式:静态导入和动态导入。 静态导入 静态导入在JSP编译的时候就会被执行。即将被导入的页面会在编译期间被插入到包含该页面的页面中。因此,被导入的页面不能是动态生成的数据。下面是一个静态导入的示例: <%@ i…

    Java 2023年6月15日
    00
  • 教你如何使用JAVA POI

    教你如何使用JAVA POI 什么是JAVA POI JAVA POI是Apache Software Foundation开发的一组开源API,用于操作各种Microsoft Office格式的文档,例如Excel、Word、PowerPoint等。在JAVA程序中使用JAVA POI可以方便地读取、创建和修改这些文档。 安装JAVA POI 要在JAVA…

    Java 2023年5月26日
    00
  • Java(基于Struts2) 分页实现代码

    下面就为您详细讲解“Java(基于Struts2) 分页实现代码”的完整攻略。 一、实现原理 Struts2框架提供了一个简单易用的分页标签库(pagetags),通过这个标签库可以非常方便地实现分页功能。具体实现流程如下: 在JSP页面上引用struts2分页标签库的tld文件。 <%@ taglib uri=”/struts-tags” prefi…

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