ホームページ >Java >&#&チュートリアル >SpringBootのグローバル例外問題を解決する方法
SpringBoot は、Spring アプリケーションの作成、実行、デバッグ、デプロイメントなどの一連の問題を簡素化するために生まれた製品です。自動アセンブリの機能により、外部の XML ではなくビジネス自体に集中できるようになります。仕様に従い、関連する依存関係を導入するだけで、簡単に WEB プロジェクトを構築できます。
実際のプロジェクト開発では、特にサーバーとしてのプログラムでさまざまな異常事態が頻繁に発生します。開発者の皆さん、私たちは常にフロントエンドの呼び出しに提供するインターフェイスを作成しています。分業と協力の場合、例外は避けられません。間違った情報がユーザーに直接さらされた場合、そのエクスペリエンスは想像できますし、実際にそうなるでしょう。ハッカーにとって、詳細な例外情報は多くの場合非常に役立ちます...
try-catch メソッドを採用して例外情報を手動で取得し、対応する結果セットを返します。同様のコードを見たことがあります (例: Result オブジェクトにカプセル化されています); このメソッドはエラーの危険性の問題を間接的に解決しますが、コードの量が増加するという同じ欠点も明らかです。例外が多すぎると、対応するキャッチがこれらのビジネス例外とエラー コードの一致を管理するのは難しいため、シンプルな構成で全体的な状況を制御するのが最善の方法です...
を見てみましょう。 Spring Boot によって提供されるソリューション
pom.xml に spring-boot-starter-web 依存関係を追加する
<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>
例外をカスタマイズする
アプリケーション開発プロセス中, ただし、システム自体の例外に加えて、さまざまなビジネス シナリオで使用される例外も異なります。「グローバル例外を簡単に取得する」のタイトルにもっと関連するように、独自の例外を定義し、キャプチャする方法を確認してください...
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; } }
例外情報のスタイルがより統一されるように、返される例外情報の形式を定義します
package com.battcn.exception; /** * @author Levin * @since public class ErrorResponseEntity private int code; private String message; // 省略 get set
通常書いたコードと同じかどうかよく見てください。何が違うのでしょうか。心配しないで読み続けてください...
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:"
アノテーションの概要:
@ControllerAdviceController 層がスローした例外をキャッチする @ResponseBody を付加すると、返される情報は JSON 形式になります。
@RestControllerAdvice@ControllerAdvice と @ResponseBody の組み合わせと同等です。
@ExceptionHandlerコードの重複と複雑さを軽減するために、1 種類の例外を統一的に処理します。
GlobalExceptionHandler クラスを作成し、 @RestControllerAdvice アノテーションを追加して例外通知クラスを定義し、定義されたメソッドに @ExceptionHandler を追加して例外キャプチャを実現します...
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); } }
準備が完了したら、Chapter17Applicationを起動してください。以下のテスト結果を見ると、非常に簡単で、コードもすっきりし、スケーラビリティも向上していることがわかります...
http://localhost:8080/test3にアクセスします
{"code":400,"message":"num不能为空"}
http://localhost:8080/test3?num=0
{"code":400,"message":"/ by zero"}
にアクセスしますhttp://localhost:8080 /test3?num=5
result:2
以上がSpringBootのグローバル例外問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。