一、前言
spring mvc下,在controller控制类中,标注了@ResponseBody的方法正常来说返回的是json对象,有时候还想额外在特定条件下处理一些数据(使用if),又或者是每个返回json数据的方法都可能需要做同样的处理,就需要使用@RestControllerAdvice标注方法进行统一处理。
这样做最大的好处就是不用修改原来的controller,以及可以所有controller通用,处理较为灵活。
二、前期准备,新建Result包装类
该类用于收集以及格式化输出最终数据
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数据进行统一处理
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:开启*/@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {return true;}/*** 处理返回结果*/@Overridepublic 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);}
}
四、测试
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {@ResponseBody@GetMapping(path = "/my_test")public String MyTest() {return "测试";}}
返回的字符串
{code:0,data:"测试",msg:"成功"}
五、注意事项
1、实测,如果数据库报错,直接跳走了,不会执行到ResponseAdvice方法,建议转到统一异常处理处进行处理。