2
votes

Java crée une classe d'exception personnalisée avec un code d'état spécifique

Dans Spring Boot, je crée une classe d'exception personnalisée avec un code d'état spécifique, et je l'appelle pour lancer une exception avec le code: 100 et le message: "No have content" au contrôleur, mais la sortie renvoie toujours "status": 500 et " erreur ":" Erreur interne du serveur "

AppException.java

{
    "timestamp": 1550987372934,
    "status": 100,
    "error": "No have content",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

UserController.java

{
    "timestamp": 1550987372934,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

Résultat réel:

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping()
    public ApiResponseDto getAllUsers(Pageable pageable) {
        Page<User> users = userService.getAllUsers(pageable);

        if (users.getSize() < 0) {
            throw new AppException(100, "No have content");
        }

        return new ApiResponseDto(HttpStatus.OK.value(), users);
    }

Mes attentes:

public class AppException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private final Integer code;

    public AppException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }
}


0 commentaires

3 Réponses :


4
votes

Si vous souhaitez une gestion globale des exceptions pour votre API, et préférez avoir des réponses d'erreur personnalisées, vous pouvez ajouter @ControllerAdvice :

@ControllerAdvice
public class ApiExceptionHandler {

    @ExceptionHandler({ ApiException.class })
    protected ResponseEntity<ApiErrorResponse> handleApiException(ApiException ex) {
        return new ResponseEntity<>(new ApiErrorResponse(ex.getStatus(), ex.getMessage(), Instant.now()), ex.getStatus());
    }
}

// you can put any information you want in ApiErrorResponse 
public class ApiErrorResponse {

    private final HttpStatus status;
    private final String message;
    private final Instant timestamp;

    public ApiError(HttpStatus status, String message, Instant timestamp) {
        this.status= status;
        this.message = message;
        this.timestamp = timestamp;
    }

    public HttpStatus getStatus() { 
        return this.status; 
    }

    public String getMessage() {
        return this.message;
    }

    public Instant getTimestamp() {
        return this.timestamp;
    }
}

// your custom ApiException class
public class ApiException extends RuntimeException {

    private final HttpStatus status;

    public ApiException(HttpStatus status, String message) {
        super(message);
        this.status = status;
    }

    public HttpStatus getStatus() {
        return this.status;
    }
}

p >


4 commentaires

Merci, mais lancez une nouvelle AppException (100, "No have content"); est un exemple. Parce que je souhaite utiliser la classe AppException pour beaucoup de mon code d'état dans le projet


@Tony J'ai mis à jour la réponse au cas où vous voudriez avoir une gestion globale des exceptions pour votre API, et préférez avoir des réponses d'erreur personnalisées.


merci, mais je veux lancer une exception à n'importe quelle classe de service, classe java, ..., pas de retour pour le contrôleur. btw, en utilisant @ControllerAdvice, il ne renvoie pas non plus exactement le code d'état que j'ai mis pour ApiException (code entier, message String). Pouvez-vous me suggérer une autre façon?


@Tony Exception peut être lancée n'importe où dans votre code. Utilisez également HttpStatus au lieu de Integer dans ApiException .



1
votes

Il existe plusieurs façons d'y parvenir:

  1. Vous pouvez ajouter une méthode annotée @ExceptionHandler dans votre contrôleur:

    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void handleException() {
    //
    }
    

  2. Vous pouvez également implémenter un résolveur personnalisé pour intercepter toutes les exceptions et les gérer globalement en remplaçant la méthode doResolveException

Plus de détails sur les deux approches ci-dessus peuvent être trouvés ici: https://www.baeldung.com/exception-handling-for-rest-with-spring


0 commentaires

1
votes

Si vous avez besoin d'un nombre limité de messages d'erreur différents ou si vous souhaitez réutiliser le même plusieurs fois, c'est tout ce dont vous avez besoin:

throw new AppException();

Pas besoin de classes et de gestionnaires supplémentaires . Votre code sera clair et simple.

Vous pouvez simplement le monter comme ceci:

@ResponseStatus(value = HttpStatus.CONTINUE, reason = "No have content")
public class AppException extends RuntimeException {
    private static final long serialVersionUID = 1L;
}


0 commentaires