使用@RestControllerAdvice统一处理@ResponseBody的返回前端数据

一、前言

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 {
    private int code;
    private String message;
    private T data;

    /**
     * 成功
     */
    public static  Result success(T data) {
        Result result = new Result();
        result.setCode(ResultMsgEnum.SUCCESS.getCode());
        result.setMessage(ResultMsgEnum.SUCCESS.getMessage());
        result.setData(data);
        return result;
    }


    /**
     * 失败,自己输入失败code和message
     */
    public static  Result 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 {

    /**
     * 是否开启功能 true:开启
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class> aClass) {
        return true;
    }

    /**
     * 处理返回结果
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class> 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方法,建议转到统一异常处理处进行处理。

你可能感兴趣的:(spring,spring,mvc)