一、前言
spring mvc下,在controller控制类中,标注了@ResponseBody的方法正常来说返回的是json对象,有时候还想额外在特定条件下处理一些数据(使用if),又或者是每个返回json数据的方法都可能需要做同样的处理,就需要使用@RestControllerAdvice标注方法进行统一处理。
这样做最大的好处就是不用修改原来的controller,以及可以所有controller通用,处理较为灵活。
二、前期准备,新建Result包装类
该类用于收集以及格式化输出最终数据
java
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> {
private int code;
private String message;
private T data;
/**
* 成功
*/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<T>();
result.setCode(ResultMsgEnum.SUCCESS.getCode());
result.setMessage(ResultMsgEnum.SUCCESS.getMessage());
result.setData(data);
return result;
}
/**
* 失败,自己输入失败code和message
*/
public static <T> Result<T> error(int code, String message) {
return new Result(code, message,null);
}
public enum ResultMsgEnum {
SUCCESS(0, "成功"),
FAIL(-1, "失败"),
AUTH_ERROR(502, "授权失败!"),
SERVER_BUSY(503, "服务器正忙,请稍后再试!"),
DATABASE_OPERATION_FAILED(504, "数据库操作失败");
private int code;
private String message;
ResultMsgEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
}
三、实现ResponseBodyAdvice接口
该类主要实现对控制类准备返回到前端的json数据进行统一处理
java
import net.sf.json.JSONObject;
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;
import java.util.ArrayList;
import java.util.HashMap;
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {
/**
* 是否开启功能 true:开启
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
/**
* 处理返回结果
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//处理字符串类型数据
if(o instanceof String){
return JSONObject.fromObject(Result.success(o));
}
//返回类型是否已经封装
if(o instanceof Result){
return o;
}
//已经处理过的前端可以识别的格式数据跳过
if(o instanceof ArrayList || o instanceof HashMap){
return o;
}
return Result.success(o);
}
}
四、测试
java
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
@ResponseBody
@GetMapping(path = "/my_test")
public String MyTest() {
return "测试";
}
}
返回的字符串
java
{code:0,data:"测试",msg:"成功"}
五、注意事项
1、实测,如果数据库报错,直接跳走了,不会执行到ResponseAdvice方法,建议转到统一异常处理处进行处理。