Partage de technologie

SpringBoot : réponse unifiée SpringBoot et gestion unifiée des exceptions

2024-07-06

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Introduction

Lors du développement d'applications Spring Boot, la manière dont les résultats de réponse et les exceptions sont gérés a un impact crucial sur la maintenabilité, l'évolutivité et la collaboration en équipe du projet. Les résultats de réponse dispersés et la logique de gestion des exceptions conduisent souvent à un code redondant difficile à comprendre et à maintenir. Par conséquent, le retour de résultat unifié et la gestion unifiée des exceptions sont l’une des stratégies clés pour améliorer la qualité du projet.

2. Retour de résultat unifié

Unifier les retours de résultats signifie généralement définir un format de réponse standard pour toutes les méthodes du contrôleur. Cela peut être accompli en créant une ou plusieurs classes d'entités de réponse contenant des champs communs tels que le code d'état, le message et les données. Une fois que la méthode du contrôleur a traité la logique métier, elle remplira ces champs et les renverra au client.

Voyons ensuite comment obtenir un retour de résultat unifié dans SpringBoot.

1. Définir un objet de réponse commun

Créez un objet de réponse générique, définissez des scénarios de retour de réussite et d'échec et assurez-vous que l'objet de retour générique est utilisé dans l'interface.

public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

2. Définir le code d'état de réponse de l'interface

La définition d’un ensemble commun de codes d’état est l’une des clés essentielles d’un retour de résultat unifié. Cette approche améliore non seulement la convivialité et la maintenabilité de l'API, mais permet également au client d'analyser et de traiter les données de réponse plus efficacement. Elle fournit également aux développeurs d'API une norme claire et cohérente à suivre.

public enum ResultEnum {

    SUCCESS(200 ,"请求处理成功"),
    SERVICE_ERROR(500, "服务器异常,请稍后重试");

    public final Integer code;

    public final String message;

    ResultEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

3. Définir des méthodes unifiées de gestion des succès et des échecs

public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

4. Le contrôleur répond uniformément aux résultats

@GetMapping("/testResult")
 public ResponseResult test() {
     // 模拟业务逻辑
     try {
         // 假设这里有一些业务逻辑
         return ResponseResult.success("success");
     } catch (Exception e) {
         // 捕获异常并返回错误信息
         return ResponseResult.error(ResultEnum.SERVICE_ERROR);
     }
 }

3. Gestion unifiée des exceptions

La gestion unifiée des exceptions utilise un gestionnaire d'exceptions global pour capturer et gérer les exceptions émises dans le contrôleur. Cette approche évite d'écrire du code de gestion des exceptions en double dans chaque méthode de contrôleur et rend également la logique de gestion des exceptions plus centralisée et plus facile à gérer.

@RestControllerAdvice
@RestControllerAdvice est une annotation combinée, qui est une combinaison de @ControllerAdvice et @ResponseBody. Il est principalement utilisé pour fournir une configuration globale pour la couche contrôleur, telle que la gestion des exceptions, la liaison des données, le prétraitement des données, etc. Puisqu'il contient @ResponseBody, toutes les méthodes traitées par @RestControllerAdvice écriront par défaut la valeur de retour dans le corps de la réponse HTTP et définiront le Content-Type approprié.

@ExceptionHandlel
L'annotation @ExceptionHandler est utilisée pour marquer une méthode qui gère les exceptions levées dans le contrôleur. Lorsqu'une méthode du contrôleur lève une exception, Spring recherchera une méthode annotée @ExceptionHandler capable de gérer l'exception. Si tel est le cas, la méthode est appelée et sa réponse est renvoyée.

Avis

当使用@ControllerAdvice时,我们需要将@ResponseBody添加到异常处理方法上。
如果我们使用@RestControllerAdvice,就不需要添加。

1. Définir les classes d'exceptions métier

Les classes d'exceptions unifiées peuvent vous aider à mieux gérer les erreurs et les exceptions, rendant ainsi la gestion des erreurs dans l'ensemble du système plus cohérente et prévisible.

public class BusinessException extends RuntimeException{

    private final ResultEnum resultEnum;

    public BusinessException(ResultEnum resultEnum, String message) {
        super(message);
        this.resultEnum = resultEnum;
    }

    public BusinessException(ResultEnum resultEnum) {
        this(resultEnum, resultEnum.message);
    }


}

2. Gestionnaire d'exceptions global

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({BusinessException.class})
    public ResponseResult handleBusinessException(BusinessException businessException, HttpServletRequest request) {
        // 想处理的业务
        return ResponseResult.error(ResultEnum.SERVICE_ERROR, businessException.getMessage());
    }

    /**
     * 其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseResult handleOtherExceptions(Exception e) {
        // 这里可以根据不同的异常类型返回不同的状态码和消息
        // 但为了简单起见,这里只返回一个通用的错误信息
        return ResponseResult.error(ResultEnum.SERVICE_ERROR);
    }

}

3. Traitement et utilisation unifiés

@GetMapping("/testException1")
    public ResponseResult test1() {
        if (true) {
            // 业务场景
            throw new BusinessException(ResultEnum.SERVICE_ERROR);
        }

        return ResponseResult.success("success");
    }

Avantages de l’utilisation d’une gestion unifiée des exceptions

réutilisation du code : évitez d'écrire des résultats de réponse et des codes de gestion des exceptions similaires à plusieurs endroits.

Facile à maintenir: Lorsque le format de réponse ou la logique de gestion des exceptions doit être modifié, il suffit de le modifier à un seul endroit.

Travail en équipe: Les membres de l'équipe peuvent plus facilement comprendre et suivre les normes de codage unifiées.

Évolutivité: Si vous devez ajouter de nouveaux types de réponses ou une logique de gestion des exceptions, étendez simplement ceux existants.