This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

Better read with global exception handling

(a) why is it necessary to return a unified data format

  1. In the normal development process, because the front end shows a variety of interfaces, so the data will have a variety of structures, if the background data is not encapsulated, the data format will be strange, and ultimately reduce the development efficiency, so the need for a unified format.
  2. In the case of an exception, the format of the exception message is also largely inconsistent with the normal return (preferably read together with global exception handling), so a unified format is needed
  3. In the process of business, some interface requests are successful, but due to business needs, some special states need to be returned. After unifying the data format, the front end can uniformly handle these states in the request entry. So you need a uniform format

(2) Implementation ideas

  1. In projects we often encapsulate a return object class in which we define the standard data format.

    Normally, we would define three parameters code, MSG, and data.

    Data Is used to save and defend service data.

    Code is used to display the unified defined status code

    MSG is used to display some basic success or failure information

  2. A status code enumeration class is also created, like this

Public enum ResultCode {SUCCESS(200," ResultCode successful "), NO_LOGIN(301," please login again "), NO_AUTH(302," You do not have permission for this function "), NO_UPDATE_DATA(303," this data cannot be operated "), NOT_ACCESS(304," access forbidden "), FAIL(5000," operation failed, please contact administrator "), CUSTOM_FAIL(5001," custom error ") // etc. private int code; private String msg; public int code(){ return this.code ; } public String msg(){ return this.msg ; } ResultCode(int code, String msg) { this.code = code; this.msg = msg; }}Copy the code

Generally speaking, for small and medium-sized projects of small and medium-sized companies, it is better to define one normal state and one abnormal state respectively, relying on MSG to display information without asking questions. If there is any problem, you can refer to the Java specification produced by Alibaba.

(3) various implementations of returned data

1. Object Receives various data

public class R implements Serializable { private int code; private String msg; private Object data ; private R() {} private R(ResultCode resultCode, String msg) { this.code = resultCode.code(); this.msg = msg; } /*** * public static R ok(Object) {/ / public static R ok(Object) {/ / public static R ok(Object) {/ / public static R ok(Object... Data){R resultVo = new R(200," operation succeeded "); resultVo.data =integrationData(data); return resultVo; } /*** * Custom exception, exception information must be returned */ public static R fail(String failMsg, Object... data){ R resultVo = new R(5000,failMsg); resultVo.data =integrationData(data); return resultVo; } / /... Contains only basic, various variants without writing... * @param data * @return */ private static Object integrationData(Object... data){ if(data==null||data.length==0){ return null; } int length = data.length; if(length==1){ return data[0]; } if(length %2 ==1){throw new RuntimeException(" +length "); } if(length %2 ==0){ HashMap<Object, Object> map = new HashMap<>(); for (int i = 0; i < length; i+=2) { map.put(data[i],data[i+1]); } return map; } return ""; }}Copy the code

use

1 R.O K (" data "); R.ok (" data1 ","KEY2"," data2 ");Copy the code

Maybe you’re looking at something like this, where if you have multiple data, you have to manually create a Map and put the data into the data

public class R<T> implements Serializable {
    private int code;
    private String msg;
    private T data ;
}
Copy the code

2. Map receives data

public class R extends HashMap<String, Object>{ public R() { put("code", 0); Put (" MSG ", "operation successful "); } public static R error(String msg) { return error(5000, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } public static R ok() { return new R(); } public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok(Object data) { return new R().put("data",data); } @Override public R put(String key, Object value) { super.put(key, value); return this; }}Copy the code

This data format is to use map to do the return object, you can like map to operate on it

1 R.O K (" data "); R.ok (" data 1"). Put ("KEY2"," data 2");Copy the code

3. The implementationResponseBodyAdviceAnd annotation@RestControllerAdvice

This method is relatively rare, and in the actual use of the process, if the communication is not smooth, the probability of problems is relatively large

@restControllerAdvice public class MyResponseAdvice implements ResponseBodyAdvice<Object> {// Enable support @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){r.ok (o)} return o; }}Copy the code

The way to use this is; In Cotroller you can write whatever you want, and in MyResponseAdvice it wraps automatically.

(4) CooperationGlobal exception handlingWhat needs to be done

See the two assigned sections of the assigned article for details:

1. Intercept 404 or server error exceptions that do not enter controller

2. Exceptions occur in user-defined codes such as filter