全局统一返回RESTful风格数据,主要是实现ResponseBodyAdvice接口的方法,对返回值在输出之前进行修改。
使用注解@RestControllerAdvice拦截异常并统一处理。
开发环境:
IntelliJ IDEA 2019.2.2
jdk1.8
Spring Boot 2.2.2
1、创建一个SpringBoot项目,pom.xml引用的依赖包如下
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
com.alibaba
fastjson
1.2.62
2、定义一个返回类
package com.example.response.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
@Data
@NoArgsConstructor
@ToString
public class ResponseData implements Serializable {
/**
* 状态码:0-成功,1-失败
* */
private int code;
/**
* 错误消息,如果成功可为空或SUCCESS
* */
private String msg;
/**
* 返回结果数据
* */
private T data;
public static ResponseData success() {
return success(null);
}
public static ResponseData success(Object data) {
ResponseData result = new ResponseData();
result.setCode(0);
result.setMsg("SUCCESS");
result.setData(data);
return result;
}
public static ResponseData fail(String msg) {
return fail(msg,null);
}
public static ResponseData fail(String msg, Object data) {
ResponseData result = new ResponseData();
result.setCode(1);
result.setMsg(msg);
result.setData(data);
return result;
}
}
3、统一拦截接口返回数据
新建一个类GlobalResponseHandler,用注解@RestControllerAdvice,并且实现ResponseBodyAdvice接口的方法,其中方法supports可以判断哪些需要拦截,方法beforeBodyWrite可以对返回值在输出之前进行修改,从而实现返回统一的接口数据。
package com.example.response.config;
import com.alibaba.fastjson.JSON;
import com.example.response.entity.ResponseData;
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.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 实现ResponseBodyAdvice接口,可以对返回值在输出之前进行修改
*/
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice
新建自定义注解IgnorReponseAdvice
package com.example.response.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnorReponseAdvice {
}
4、统一异常处理
package com.example.response.exception;
import com.example.response.entity.ResponseData;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseData exceptionHandler(Exception e) {
e.printStackTrace();
return ResponseData.fail("服务器异常:" + e.getMessage());
}
}
5、新建一个测试用的实体类
package com.example.response.entity;
import lombok.Data;
@Data
public class User {
private Long userId;
private String userName;
public User(Long userId, String userName){
this.userId = userId;
this.userName = userName;
}
}
6、新建一个测试用的控制器类
package com.example.response.controller;
import com.example.response.config.IgnorReponseAdvice;
import com.example.response.entity.ResponseData;
import com.example.response.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
public class DemoController {
@GetMapping("user")
public User user() {
User u = new User(100L, "u1");
return u;
}
@GetMapping("userList")
public List userList(){
List list = new ArrayList();
list.add(new User(100L, "u1"));
list.add(new User(200L, "u2"));
return list;
}
@GetMapping("test1")
public String test1(){
return "test1";
}
@GetMapping("test2")
public ResponseData test2(){
return ResponseData.success("test2");
}
@IgnorReponseAdvice
@GetMapping("test3")
public String test3() {
return "test3";
}
@GetMapping("test4")
public String test4() {
Integer x = 1 / 0;
return x.toString();
}
@GetMapping("test5")
public String test5() throws Exception {
throw new Exception("自定义异常信息");
}
}
7、用Postman测试
(1)请求http://localhost:8080/user,返回
{
"code": 0,
"msg": "SUCCESS",
"data": {
"userId": 100,
"userName": "u1"
}
}
(2)请求http://localhost:8080/userList,返回
{
"code": 0,
"msg": "SUCCESS",
"data": [
{
"userId": 100,
"userName": "u1"
},
{
"userId": 200,
"userName": "u2"
}
]
}
(3)请求http://localhost:8080/tes1,返回
{"msg":"SUCCESS","code":0,"data":"test1"}
(4)请求http://localhost:8080/test2,返回
{
"code": 0,
"msg": "SUCCESS",
"data": "test2"
}
(5)请求http://localhost:8080/test3,返回
test3
(6)请求http://localhost:8080/test4,返回
{
"code": 1,
"msg": "服务器异常:/ by zero",
"data": null
}
(7)请求http://localhost:8080/test5,返回
{
"code": 1,
"msg": "服务器异常:自定义异常信息",
"data": null
}
转发:spring boot 2 全局统一返回RESTful风格数据、统一异常处理 (lagou.com)