Maison  >  Article  >  Java  >  Comment résoudre le problème d'exception globale SpringBoot

Comment résoudre le problème d'exception globale SpringBoot

王林
王林avant
2023-05-16 10:49:121548parcourir

SpringBoot est un produit né pour simplifier une série de problèmes tels que la création, l'exécution, le débogage et le déploiement d'applications Spring. La fonctionnalité d'assemblage automatique nous permet de mieux nous concentrer sur l'entreprise elle-même plutôt que sur la configuration XML externe. devez suivre les spécifications, vous pouvez facilement construire un projet WEB en introduisant des dépendances pertinentes

Dans le développement réel du projet, diverses situations anormales se produisent souvent dans le programme, en particulier en tant que développeurs côté serveur, nous écrivons toujours constamment des interfaces pour fournir une interface frontale -terminer les appels, et dans le cas de la division du travail et de la coopération, les exceptions ne peuvent être évitées. Si des informations erronées sont directement exposées à l'utilisateur, l'expérience peut être imaginée, et pour les pirates informatiques, des informations détaillées sur les exceptions sont souvent fournies. Très utile. ..

Utilisez la méthode try-catch pour capturer manuellement les informations d'exception, puis renvoyez l'ensemble de résultats correspondant. Je pense que de nombreuses personnes ont vu du code similaire (tel que : encapsulé dans un objet Result bien que cette méthode soit indirecte) ; Problème d'exposition aux erreurs, les mêmes inconvénients sont également évidents. Lorsqu'il y a trop d'exceptions, les couches de capture correspondantes deviennent de plus en plus difficiles à gérer. correspondant, donc le meilleur moyen est de prendre le contrôle global grâce à une configuration simple...

Jetons un coup d'œil à la solution fournie par Spring Boot

1 Importer les dépendances

Ajoutez spring-boot-starter-web dans pom.xml Juste comptez sur

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Exceptions personnalisées
Dans le processus de développement d'applications, en plus des exceptions du système lui-même, les exceptions utilisées dans différents scénarios commerciaux sont également différentes afin d'être plus pertinentes par rapport au titre d'Obtenir facilement des exceptions globales. définissez votre propre exception, voyez comment capturer...

package com.battcn.exception;

/**
 * 自定义异常
 *
 * @author Levin
 * @since
public class CustomException extends RuntimeException

    private static final long serialVersionUID = 4564124491192825748L;

    private int code;

    public CustomException() {
        super();
    }

    public CustomException(int code, String message) {
        super(message);
        this.setCode(code);
    }

    public int getCode() {
        return code;
    }

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

2 Modèle d'informations d'exception

Définissez le format des informations d'exception renvoyées, afin que le style des informations d'exception soit plus unifié

package com.battcn.exception;

/**
 * @author Levin
 * @since
public class ErrorResponseEntity

    private int code;
    private String message;
    // 省略 get set

3 Couche de contrôle

Regardez de plus près regardez s'il est écrit normalement. Il n'y a pas de différence dans le code, ne vous inquiétez pas, continuez à lire...

package com.battcn.controller;

import com.battcn.exception.CustomException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常演示
 *
 * @author Levin
 * @since
@RestController
public class ExceptionController

    @GetMapping("/test3")
    public String test3(Integer num) {
        // TODO 演示需要,实际上参数是否为空通过 @RequestParam(required = true)  就可以控制
        if (num == null) {
            throw new CustomException(400, "num不能为空");
        }
        int i = 10 / num;
        return "result:"

4 Gestion des exceptions (clé)

Aperçu des annotations :

  • @ControllerAdviceCapture l'exception levée par la couche Controller, si @ResponseBody est ajouté, les informations de retour seront au format JSON.

  • @RestControllerAdvice est équivalent à la combinaison de @ControllerAdvice et @ResponseBody.

  • @ExceptionHandlerGère uniformément un type d'exceptions, réduisant ainsi la duplication et la complexité du code.

Créez une classe GlobalExceptionHandler et ajoutez l'annotation @RestControllerAdvice pour définir la classe de notification d'exception, puis ajoutez @ExceptionHandler à la méthode définie pour capturer l'exception...

package com.battcn.config;

import com.battcn.exception.CustomException;
import com.battcn.exception.ErrorResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理
 *
 * @author Levin
 * @since
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler


    /**
     * 定义要捕获的异常 可以多个 @ExceptionHandler({})
     *
     * @param request  request
     * @param e        exception
     * @param response response
     * @return
    @ExceptionHandler(CustomException.class)
    public ErrorResponseEntity customExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        CustomException exception = (CustomException) e;
        return new ErrorResponseEntity(exception.getCode(), exception.getMessage());
    }

    /**
     * 捕获  RuntimeException 异常
     * TODO  如果你觉得在一个 exceptionHandler 通过  if (e instanceof xxxException) 太麻烦
     * TODO  那么你还可以自己写多个不同的 exceptionHandler 处理不同异常
     *
     * @param request  request
     * @param e        exception
     * @param response response
     * @return
    @ExceptionHandler(RuntimeException.class)
    public ErrorResponseEntity runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException exception = (RuntimeException) e;
        return new ErrorResponseEntity(400, exception.getMessage());
    }

    /**
     * 通用的接口映射异常处理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(new ErrorResponseEntity(status.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
                    + ",信息:" + exception.getLocalizedMessage());
            return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "参数转换失败"), status);
        }
        return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "参数转换失败"), status);
    }
}

Test

Terminez les préparatifs Enfin, démarrez le chapitre 17Application. D'après les résultats des tests suivants, vous constaterez que c'est vraiment très simple, que le code est devenu plus propre et que l'évolutivité s'est également améliorée...

Visitez http://localhost:8080/test3

{"code":400,"message":"num不能为空"}

Visitez http: / /localhost:8080/test3?num=0

{"code":400,"message":"/ by zero"}

Visitez http://localhost:8080/test3?num=5

result:2

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer