Springboot глобальная унифицированная обработка возврата


предисловие

Как правило, в проекте будет указанный формат возврата интерфейса. Независимо от успеха или неудачи, общий формат остается неизменным. Это сделано для облегчения унифицированной обработки передней и задней частей. Сегодня мы поговорим о более элегантном способе. унифицированной обработки передней и задней частей;


1. Единый формат возврата

Вообще говоря, будет унифицированный класс возврата как инкапсуляция возвращаемых данных интерфейса, например:

@Data
public class Result<T> implements Serializable {
    
    

    private int code = HttpStatus.OK.value();

    private String msg;

    private T data;


    public static <T> Result<T> success() {
    
    
        return success(null);
    }


    public static <T> Result<T> failure() {
    
    
        return failure(HttpStatus.BAD_REQUEST.value(),HttpStatus.BAD_REQUEST.getReasonPhrase());
    }

    public static <T> Result<T> success(T data) {
    
    
        return new Result<T>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
    }

    public static <T> Result<T> failure(int errorCode, String errorMsg) {
    
    
        return failure(errorCode, errorMsg, null);
    }

    public static <T> Result<T> failure(int code, String errorMsg, T data) {
    
    
        return new Result<T>(code, errorMsg, data);
    }

    public Result(int code, String msg, T data) {
    
    
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

}

Затем мы используем этот класс как единый пакет возвращаемых параметров, поэтому независимо от того, успешен он или нет, есть три параметра
с кодом данных msg.

2. Глобальная обработка исключений

  • В проекте неизбежно будут исключения.
    1. Исключение, о котором сообщает сервер
    2. Обработка исключений в логике (проверка параметров, логический сбой и т. д.)
  • Поскольку мы обычно разделяем фронтенд- и бэкенд-проекты, все они возвращаются в виде интерфейсов, поэтому нам нужно иметь дело только с интерфейсами.
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel {
    
    

    @ExceptionHandler(ValidationException.class)
    public Result<String> handleException(ValidationException e) {
    
    
        e.printStackTrace();
        log.error("参数校验发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public Result<String> exceptionHandler(NullPointerException e) {
    
    
        e.printStackTrace();
        log.error("空指针异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(value = {
    
    Exception.class, RuntimeException.class})
    public Result<String> exceptionHandler(Exception e) {
    
    
        e.printStackTrace();
        log.error("运行时发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    public Result<String> handException(AsyncRequestTimeoutException e) {
    
    
        e.printStackTrace();
        log.error("运行时超时异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }
}

В общем, контроллер можно использовать вот так

@RestController
@RequestMapping("lang")
public class LangController {
    
    
    @RequestMapping("get")
    public Result get(){
    
    
        return Result.success(LocalUtil.get("demo"));
    }
}

3. Глобальная обработка возврата (для притворства)

Это по-прежнему глобальная обработка исключений, описанная выше, но нужно кое-что добавить.

  • Реализуйте интерфейс ResponseBodyAdvice.
  • Реализуйте два метода.Полный
    код выглядит следующим образом:
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel implements ResponseBodyAdvice<Object>{
    
    

    @Autowired
    private ObjectMapper objectMapper;

    @ExceptionHandler(ValidationException.class)
    public Result<String> handleException(ValidationException e) {
    
    
        e.printStackTrace();
        log.error("参数校验发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public Result<String> exceptionHandler(NullPointerException e) {
    
    
        e.printStackTrace();
        log.error("空指针异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(value = {
    
    Exception.class, RuntimeException.class})
    public Result<String> exceptionHandler(Exception e) {
    
    
        e.printStackTrace();
        log.error("运行时发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    public Result<String> handException(AsyncRequestTimeoutException e) {
    
    
        e.printStackTrace();
        log.error("运行时超时异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
    
    
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    
    

        Class<?> returnClass = returnType.getMethod().getReturnType();
        if (body instanceof String || Objects.equals(returnClass, String.class)) {
    
    
            return objectMapper.writeValueAsString(Result.success(body));
        }
        if (body instanceof Result) {
    
    
            return body;
        }
        return Result.success(body);
    }
}

Таким образом, контроллер можно использовать, как и раньше, или следующим образом
: он автоматически инкапсулирует возвращаемый результат без инкапсуляции вручную.

@RestController
@RequestMapping("lang")
public class LangController {
    
    

    @RequestMapping("get")
    public String get(){
    
    
        return LocalUtil.get("demo");
    }
}

Подведем итог

Если в проекте таким образом следовать интерфейсу @RestControllerAdvice + ResponseBodyAdvice, можно реализовать большинство унифицированных функций возврата и вывода. Будь то обычный запрос или ненормальный запрос, простой тип или возврат коллекции, это эквивалент унифицированного пакета.Обработка;
попробуйте быстро и используйте в проекте~

おすすめ

転載: blog.csdn.net/qq_32419139/article/details/131764848