スプリングブート例外処理の例
44187 ワード
このチュートリアルでは、使用するスプリングブート例外処理の例を見ていきます
RESTful API例外を処理することもできます
@RestControllerAdvice example in Spring Boot
この記事は本来はBezkoder .
API APIの残りの処理
我々は、CRUD操作とFinderメソッドのためのRESTコントローラを作成しました.
コードを見てみましょう.
以下の手順を実行します. Spring Boot Data JPA + H2 CRUD example Spring Boot Data JPA + MySQL CRUD example Spring Boot Data JPA + PostgreSQL CRUD example Spring Boot Data JPA + SQL Server Spring Boot Data JPA + Oracle example Spring Boot MongoDB CRUD example
Spring Boot Cassandra CRUD example )
それらを単純に保つ方法はありますか、エラー応答メッセージをスマートに、そして、柔軟性を付けるどんな方法でもありますか?
今問題を解決しましょう.
春のコントローラアドバイスによる例外処理
Springグローバルな例外ハンドラーによる例外処理をサポートします.@ExceptionHandler ) コントローラのアドバイス@ControllerAdvice ). これは、作るメカニズムを可能にする
そのメソッド
二つの注釈を一緒に使うことで、 ステータスコードと共にレスポンスの本体を制御する 同じメソッドでいくつかの例外を扱います 応答ステータス
上の例では
春も提供
次のいずれかの手順でソースコードを取得するか、または次のいずれかの手順で取得できます. Spring Boot Data JPA + H2 CRUD example Spring Boot Data JPA + MySQL CRUD example Spring Boot Data JPA + PostgreSQL CRUD example Spring Boot Data JPA + SQL Server Spring Boot Data JPA + Oracle example Spring Boot MongoDB CRUD example Spring Boot Cassandra CRUD example Springプロジェクトには、いくつかの変更を追加する必要があります.
または、このチュートリアルの最後に新しいGithubソースコードを取得できます.
最終的なプロジェクト構造は次のようになります.
エラー応答メッセージ
私たちは、春のブートによって提供されるデフォルトのエラー応答を使用する代わりに、私たち自身のメッセージ応答構造を作成したいです.
特定のエラー応答構造を定義しましょう.
例外/エラーメッセージ.ジャバ
私たちは、スプリングブートコントローラで見つけられないリソースの例外をスローします.
レットクリエイト
例外/ResourceObjecdException.ジャバ
今私たちは特別なクラスを作成するつもりです
例外/ControllerExceptionハンドラ.ジャバ
私たちの残りのコントローラは、今/tryブロックをキャッチしていないとスローされます
コントローラ/チュートリアルコントローラ.ジャバ
CRUD REST APIと例外処理の実行を終了します.
コマンドを実行して起動する 存在しないチュートリアルを取得する 存在しないチュートリアルを更新します 間違ったフィールドでチュートリアルを作成します 存在しないチュートリアルを削除します
結論
今日、我々はスプリングブートレストAPIのための例外処理クラスを構築しました
このスプリングプロジェクトにページネーションを追加する場合は、次の手順を実行できます.
Spring Boot Pagination & Filter example | Spring JPA, Pageable
複数のフィールドを並べ替えたり並べたりするには、次の手順に従います.
Spring Data JPA Sort/Order by multiple Columns | Spring Boot
またはJPAリポジトリの単位テストを書く方法
Spring Boot Unit Test for JPA Repositiory with @DataJpaTest
また、AWS(無料で)でこの春のブートアプリを展開する方法を知ることができますthis tutorial .
またはDocker Compose: Spring Boot and MySQL example
ハッピーラーニング!また会いましょう.
更なる読書
関連記事: Spring Boot, Spring Data JPA – Rest CRUD API example Spring Boot Pagination & Filter example Spring Boot Sort/Order by multiple Columns その他の実践 Spring Boot Multipart File upload example Spring Boot Token based Authentication with Spring Security & JWT ソースコード
このチュートリアルの完全なソースコードを見つけることができますGithub .
@ControllerAdvice
and @ExceptionHandler
.RESTful API例外を処理することもできます
@RestControllerAdvice
, 親愛なる訪問@RestControllerAdvice example in Spring Boot
この記事は本来はBezkoder .
API APIの残りの処理
我々は、CRUD操作とFinderメソッドのためのRESTコントローラを作成しました.
コードを見てみましょう.
以下の手順を実行します.
Spring Boot Cassandra CRUD example )
@RestController
public class TutorialController {
@Autowired
TutorialRepository tutorialRepository;
@GetMapping("/tutorials")
public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
try {
...
return new ResponseEntity<>(tutorials, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/tutorials/{id}")
public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
Optional<Tutorial> tutorialData = tutorialRepository.findById(id);
if (tutorialData.isPresent()) {
return new ResponseEntity<>(tutorialData.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PutMapping("/tutorials/{id}")
public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
Optional<Tutorial> tutorialData = tutorialRepository.findById(id);
if (tutorialData.isPresent()) {
...
return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
...
@DeleteMapping("/tutorials/{id}")
public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
try {
tutorialRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/tutorials")
public ResponseEntity<HttpStatus> deleteAllTutorials() {
// try and catch
}
@GetMapping("/tutorials/published")
public ResponseEntity<List<Tutorial>> findByPublished() {
// try and catch
}
}
同じような例外に対してtry/catchを何度も使っていることがわかります.それらを単純に保つ方法はありますか、エラー応答メッセージをスマートに、そして、柔軟性を付けるどんな方法でもありますか?
今問題を解決しましょう.
春のコントローラアドバイスによる例外処理
Springグローバルな例外ハンドラーによる例外処理をサポートします.@ExceptionHandler ) コントローラのアドバイス@ControllerAdvice ). これは、作るメカニズムを可能にする
ResponseEntity
タイプの安全性と柔軟性@ExceptionHandler
:@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(value = {ResourceNotFoundException.class, CertainException.class})
public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(
status,
date,
ex.getMessage(),
description);
return new ResponseEntity<ErrorMessage>(message, HttpStatus.NOT_FOUND);
}
}
The @ControllerAdvice
注釈は@Component
注釈は、それがCLASSPATHのスキャンを介して自動検出されるように.コントローラアドバイスは、我々のコントローラのロジックを囲む一種のインターセプターで、私たちが彼らにいくつかの共通のロジックを適用するのを許します.そのメソッド
@ExceptionHandler
) を共有する@Controller
コンポーネントは、例外をキャプチャし、HTTP応答にそれらを翻訳します.The @ExceptionHandler
注釈は、どのタイプの例外を処理するかを示します.The exception
インスタンスとrequest
メソッド引数を通して注入されます.二つの注釈を一緒に使うことで、
上の例では
@ControllerAdvice
REST Webサービスとリターンの場合ResponseEntity
オブジェクトを追加します.春も提供
@ResponseBody
注釈を返すと、オブジェクトが自動的にシリアル化され、JSONに渡されますHttpResponse
オブジェクト.この方法は必要ありませんResponseEntity
しかし、使用する必要があります@ResponseStatus
HTTPステータスコードを設定します.
@ControllerAdvice
@ResponseBody
public class ControllerExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public ErrorMessage resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(...);
return message;
}
}
セットアップスプリングブートプロジェクト次のいずれかの手順でソースコードを取得するか、または次のいずれかの手順で取得できます.
または、このチュートリアルの最後に新しいGithubソースコードを取得できます.
最終的なプロジェクト構造は次のようになります.
エラー応答メッセージ
私たちは、春のブートによって提供されるデフォルトのエラー応答を使用する代わりに、私たち自身のメッセージ応答構造を作成したいです.
特定のエラー応答構造を定義しましょう.
例外/エラーメッセージ.ジャバ
package com.bezkoder.spring.exhandling.exception;
import java.util.Date;
public class ErrorMessage {
private int statusCode;
private Date timestamp;
private String message;
private String description;
public ErrorMessage(int statusCode, Date timestamp, String message, String description) {
this.statusCode = statusCode;
this.timestamp = timestamp;
this.message = message;
this.description = description;
}
public int getStatusCode() {
return statusCode;
}
public Date getTimestamp() {
return timestamp;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
}
カスタム例外の作成私たちは、スプリングブートコントローラで見つけられないリソースの例外をスローします.
レットクリエイト
ResourceNotFoundException
拡張クラスRuntimeException
.例外/ResourceObjecdException.ジャバ
package com.bezkoder.spring.exhandling.exception;
public class ResourceNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ResourceNotFoundException(String msg) {
super(msg);
}
}
コントローラのアドバイスを今私たちは特別なクラスを作成するつもりです
@ControllerAdvice
注釈.このクラスは、特定の例外を処理しますResoureNotFoundException
) つの場所だけでグローバルな例外.例外/ControllerExceptionハンドラ.ジャバ
package com.bezkoder.spring.exhandling.exception;
import java.util.Date;
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.context.request.WebRequest;
import com.bezkoder.spring.exhandling.exception.ErrorMessage;
import com.bezkoder.spring.exhandling.exception.ResourceNotFoundException;
@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(
HttpStatus.NOT_FOUND.value(),
new Date(),
ex.getMessage(),
request.getDescription(false));
return new ResponseEntity<ErrorMessage>(message, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
new Date(),
ex.getMessage(),
request.getDescription(false));
return new ResponseEntity<ErrorMessage>(message, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
を使用してコントローラを変更私たちの残りのコントローラは、今/tryブロックをキャッチしていないとスローされます
ResourceNotFoundException
ここで応答メッセージにNoCount発見通知を送りたい.コントローラ/チュートリアルコントローラ.ジャバ
package com.bezkoder.spring.exhandling.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.bezkoder.spring.exhandling.exception.ResourceNotFoundException;
import com.bezkoder.spring.exhandling.model.Tutorial;
import com.bezkoder.spring.exhandling.repository.TutorialRepository;
@CrossOrigin(origins = "http://localhost:8081")
@RestController
@RequestMapping("/api")
public class TutorialController {
@Autowired
TutorialRepository tutorialRepository;
@GetMapping("/tutorials")
public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
List<Tutorial> tutorials = new ArrayList<Tutorial>();
if (title == null)
tutorialRepository.findAll().forEach(tutorials::add);
else
tutorialRepository.findByTitleContaining(title).forEach(tutorials::add);
if (tutorials.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(tutorials, HttpStatus.OK);
}
@GetMapping("/tutorials/{id}")
public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
Tutorial tutorial = tutorialRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));
return new ResponseEntity<>(tutorial, HttpStatus.OK);
}
@PostMapping("/tutorials")
public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {
Tutorial _tutorial = tutorialRepository.save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), false));
return new ResponseEntity<>(_tutorial, HttpStatus.CREATED);
}
@PutMapping("/tutorials/{id}")
public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
Tutorial _tutorial = tutorialRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));
_tutorial.setTitle(tutorial.getTitle());
_tutorial.setDescription(tutorial.getDescription());
_tutorial.setPublished(tutorial.isPublished());
return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
}
@DeleteMapping("/tutorials/{id}")
public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
tutorialRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@DeleteMapping("/tutorials")
public ResponseEntity<HttpStatus> deleteAllTutorials() {
tutorialRepository.deleteAll();
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@GetMapping("/tutorials/published")
public ResponseEntity<List<Tutorial>> findByPublished() {
List<Tutorial> tutorials = tutorialRepository.findByPublished(true);
if (tutorials.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(tutorials, HttpStatus.OK);
}
}
実行とテストCRUD REST APIと例外処理の実行を終了します.
コマンドを実行して起動する
mvn spring-boot:run
.結論
今日、我々はスプリングブートレストAPIのための例外処理クラスを構築しました
@ControllerAdvice
and @ExceptionHandler
. これで、独自のカスタム例外ハンドラークラスを作成したり、簡単に1つの場所でグローバル例外を処理できます.このスプリングプロジェクトにページネーションを追加する場合は、次の手順を実行できます.
Spring Boot Pagination & Filter example | Spring JPA, Pageable
複数のフィールドを並べ替えたり並べたりするには、次の手順に従います.
Spring Data JPA Sort/Order by multiple Columns | Spring Boot
またはJPAリポジトリの単位テストを書く方法
Spring Boot Unit Test for JPA Repositiory with @DataJpaTest
また、AWS(無料で)でこの春のブートアプリを展開する方法を知ることができますthis tutorial .
またはDocker Compose: Spring Boot and MySQL example
ハッピーラーニング!また会いましょう.
更なる読書
関連記事:
このチュートリアルの完全なソースコードを見つけることができますGithub .
Reference
この問題について(スプリングブート例外処理の例), 我々は、より多くの情報をここで見つけました https://dev.to/tienbku/spring-boot-exception-handling-example-241cテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol