ホームページ >Java >&#&チュートリアル >Spring Boot での例外処理

Spring Boot での例外処理

PHPz
PHPzオリジナル
2024-07-25 06:35:12611ブラウズ

Exception Handling in Spring Boot

例外処理は、堅牢でユーザーフレンドリーなアプリケーションを構築する上で重要な部分です。 Spring Boot では、アプリケーションの安定性を確保し、ユーザーに有意義なフィードバックを提供するために、さまざまな方法で例外を処理できます。このガイドでは、カスタム例外、グローバル例外処理、検証エラー、運用環境のベスト プラクティスなど、例外処理のさまざまな戦略について説明します。

1. 例外処理の基本

例外は、プログラムの通常の流れを中断するイベントです。それらは次のように分類できます:

  • チェックされた例外: コンパイル時にチェックされる例外。
  • 未チェックの例外 (実行時例外): 実行時に発生する例外。
  • エラー: OutOfMemoryError など、アプリケーションが処理すべきではない重大な問題。

2. カスタム例外クラス

カスタム例外クラスを作成すると、アプリケーション内の特定のエラー状態を処理するのに役立ちます。

package com.example.SpringBootRefresher.exception;

public class DepartmentNotFoundException extends RuntimeException {
    public DepartmentNotFoundException(String message) {
        super(message);
    }
}

3. コントローラーでの例外処理

@ExceptionHandler 注釈:
コントローラー クラスで例外を処理するメソッドを定義できます。

package com.example.SpringBootRefresher.controller;

import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DepartmentController {

    @GetMapping("/department")
    public String getDepartment() {
        // Simulate an exception
        throw new DepartmentNotFoundException("Department not found!");
    }

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity<String> handleDepartmentNotFoundException(DepartmentNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

4. @ControllerAdvice によるグローバル例外処理

例外をグローバルに処理するには、@ControllerAdvice と集中例外ハンドラーを使用できます。

package com.example.SpringBootRefresher.error;

import com.example.SpringBootRefresher.entity.ErrorMessage;
import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
@ResponseStatus
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity<ErrorMessage> handleDepartmentNotFoundException(DepartmentNotFoundException exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.NOT_FOUND.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(message);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorMessage> handleGlobalException(Exception exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(message);
    }
}

5. 標準エラー応答の作成

標準エラー応答クラスを定義して、エラー メッセージを構造化します。

package com.example.SpringBootRefresher.entity;

public class ErrorMessage {
    private int statusCode;
    private String message;
    private String description;

    public ErrorMessage(int statusCode, String message, String description) {
        this.statusCode = statusCode;
        this.message = message;
        this.description = description;
    }

    // Getters and setters

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

6. 検証エラーの処理

Spring Boot は Bean Validation (JSR-380) とうまく統合されています。検証エラーをグローバルに処理するには、@ControllerAdvice.
を使用します。

package com.example.SpringBootRefresher.error;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
@ResponseStatus
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}

7. 単純な例外に対する @ResponseStatus の使用

単純なケースでは、例外クラスに @ResponseStatus の注釈を付けて、HTTP ステータス コードを指定できます。

package com.example.SpringBootRefresher.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class DepartmentNotFoundException extends RuntimeException {
    public DepartmentNotFoundException(String message) {
        super(message);
    }
}

8. 本番環境のベストプラクティス

  1. 一貫したエラー応答: アプリケーションが一貫性のある構造化されたエラー応答を返すようにします。標準エラー応答クラスを使用します。
  2. ログ: デバッグと監視の目的で例外をログに記録します。機密情報がログに漏洩しないようにしてください。
  3. ユーザーフレンドリーなメッセージ: ユーザーフレンドリーなエラーメッセージを提供します。内部の詳細やスタック トレースをユーザーに公開しないでください。
  4. セキュリティ: 機密データの公開を避けるため、エラー応答に含まれる情報には注意してください。
  5. ドキュメント: チームと将来のメンテナーのために例外処理戦略を文書化します。

まとめ

Spring Boot での例外処理には、@ExceptionHandler、@ControllerAdvice、@ResponseStatus などのアノテーションを使用してエラーを効果的に管理することが含まれます。カスタム例外を作成し、検証エラーを処理し、ベスト プラクティスに従うことで、エラーを適切に処理し、ユーザーに有意義なフィードバックを提供する堅牢なアプリケーションを構築できます。 Java 17 の機能を使用すると、アプリケーションは Java エコシステムの最新の改善点を確実に活用できます。

以上がSpring Boot での例外処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。