SpringBoot項目接口統一響應處理、統一異常處理、統一配置

ResponseBodyAdvice 接口實現自定義返回數據類型

api接口中都是需要定義一個統一的響應頭來返回json數據

一般方法是通過在返回時構造一個響應頭對象如下:

public class ApiR extends HashMap<String, Object> {
	private static final long serialVersionUID = 1L;

	public ApiR() {
		put("code", 200);
		put("msg", "success");
	}
	
	public static ApiR error() {
		return error(500, "未知異常,請聯繫管理員");
	}
	
	public static ApiR error(String msg) {
		return error(500, msg);
	}
	
	public static ApiR error(int code, String msg) {
		ApiR r = new ApiR();
		r.put("code", code);
		r.put("msg", msg);
		return r;
	}

	public static ApiR ok(String msg) {
		ApiR r = new ApiR();
		r.put("msg", msg);
		return r;
	}

	public static ApiR ok(Object obj) {
		ApiR r = new ApiR();
		r.put("code",200);
		r.put("results", obj);
		return r;
	}
	
	public static ApiR ok(Map<String, Object> map) {
		ApiR r = new ApiR();
		r.putAll(map);
		return r;
	}
	
	public static ApiR ok() {
		return new ApiR();
	}

	public static ApiR setResults(Object object) {
		ApiR r = ApiR.ok();
		r.put("code",200);
		r.put("results", object);
		return r;
	}

	@Override
	public ApiR put(String key, Object value) {
		super.put(key, value);
		return this;
	}
}

在返回是使用ApiR

return ApiR.setResults(list);

這種弊端是每個響應都需要加響應頭對象。

我們可以通過統一響應處理

統一處理的響應頭對象

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResponse<T> implements Serializable {
    private Integer code;
    private String msg;
    private T data;

    public CommonResponse(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

通過@RestControllerAdvice來實現,ResponseBodyAdvice的作用是在響應體返回之前做一些自定義的處理工作。通常,我們會實現ResponseBodyAdvice接口,幷包裝統一的響應返回。

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {
    @Override
    @SuppressWarnings("all")
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        //如果類有IgnoreResponseAdvice這個註解就不處理
        if(methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )){
            return false;
        }
        //如果方法有IgnoreResponseAdvice這個註解就不處理
        if(methodParameter.getMethod().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )){
            return false;
        }
        return true;
    }
    //Object,這個就是原始的Controller返回的內容。我們也就是需要對它進行包裝
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        CommonResponse<Object> response = new CommonResponse<>(0,"");
        //如果是null response不需要設置data
        if(null == o){
            return response;
            //如果o是CommonResponse實例 強轉
        }else if(o instanceof  CommonResponse){
            response = (CommonResponse<Object>) o;
        }else{
            // 否則, 把響應對象作爲 CommonResponse 的 data 部分
            response.setData(o);
        }
        return response;
    }
}

統一異常處理

業務異常類

public class ReException extends Exception{
    public ReException(String message){
        super(message);
    }
}

異常處理,也需要統一響應頭

@RestControllerAdvice
public class GlobalExceptionAdvice {

    @ExceptionHandler(value = ReException.class)
    public CommonResponse<String> handlerReException(HttpServletRequest request,ReException re){
        //統一異常接口的響應
        //建議使用枚舉
        CommonResponse<String> response = new CommonResponse<>(-1,"business error");
        response.setData(re.getMessage());
        return response;
    }
}

統一配置json

通過繼承WebMvcConfigurer類重寫configureMessageConverters方法
MappingJackson2HttpMessageConverter實現了HttpMessageConverter接口。HttpMessageConverter接口有canRead和canWrite方法。完成json轉化

@Configuration
public class WebConfiguration implements WebMvcConfigurer{
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.clear();
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章