下面我来详细讲解一下“Spring Boot 统一 JSON 格式的接口返回结果的实现”攻略。
1. 前言
在实际的项目中,我们往往需要为每个接口编写返回数据的格式,这样很浪费时间。而使用统一的 JSON 返回格式,不仅可以减少代码量,还能让前端开发更加便捷。本文将明确探讨在 Spring Boot 中如何实现这一目标。
2. 统一 JSON 格式的接口返回结果的实现
我们可以通过使用 Spring Boot 提供的拦截器、自定义注解、统一异常处理等来实现统一 JSON 格式的接口返回结果。下面分别介绍这三种方式的实现方法。
2.1 使用拦截器
我们可以通过编写拦截器,在接口调用完毕后修改返回的 JSON 格式。具体实现步骤如下:
- 创建一个拦截器类,实现
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));
}
}
}
}
```
- 创建一个注解
ApiResult
,标记需要统一 JSON 格式返回结果的方法。
java
/**
* ApiResult 注解,标记需要统一 JSON 格式返回结果的方法
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiResult {
}
- 注册拦截器,放行操作
```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);
}
}
```
- 在需要统一 JSON 格式返回结果的方法上加上
@ApiResult
注解即可。
java
/**
* 测试需要统一 JSON 格式返回结果的方法
* @return 返回 JSON 格式的数据
*/
@ApiResult
@GetMapping("/testJson")
public ApiResultVO<String> testJson() {
return ApiResultVO.success("测试成功");
}
2.2 使用自定义注解
我们可以通过自定义注解来实现简化操作。具体实现步骤如下:
- 创建一个注解
JsonResultFormat
,标记需要统一 JSON 格式返回结果的类或方法。
java
/**
* JsonResultFormat 注解,标记需要统一 JSON 格式返回结果的类或方法
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonResultFormat {
}
- 创建一个拦截器类
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));
}
}
}
}
```
- 注册拦截器
```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);
}
}
```
- 在需要统一 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;
}
最后需要注意的是,在 ApiResultVO
和 JsonResult
中,code
字段用于标记接口状态码,一般正常情况下为 0,而 msg
字段用于返回处理结果描述信息,data
字段返回数据内容。
3. 总结
本文介绍了三种实现统一 JSON 格式的接口返回结果的方法,分别是使用拦截器、自定义注解和统一异常处理。通过实现统一的返回格式,可以减少代码量,提升开发效率。同时,通过统一异常处理的方式,还可以将错误信息封装成统一 JSON 格式返回给前端,便于前端程序员查看和处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring boot 统一JSON格式的接口返回结果的实现 - Python技术站