SSM統合詳細ティーチング(中)
3. 例外ハンドラ
問題のインポート
質問 1: 例外はプロジェクトのすべてのレベルで発生する可能性がありますが、例外処理コードはどのレベルで記述されますか?
1 例外の概要
- プログラム開発の過程では必ず異常現象が発生しますが、そのようなページデータをユーザーに見せることはできません。
- 異常現象の一般的な場所と一般的な原因は次のとおりです。
- フレームワーク内で例外がスローされました: 準拠していない使用が原因です
- データ層によってスローされた例外: 外部サーバーの障害が原因 (例: サーバー アクセス タイムアウト)
- ビジネス層によってスローされる例外: ビジネス ロジックの記述エラーが原因 (例: ビジネスの記述操作を走査し、インデックス例外が発生するなど)
- プレゼンテーション層によってスローされる例外: データ収集や検証などのルールによって発生します (例: データ型の不一致によって発生する例外)。
- ツール クラスによってスローされた例外: ツール クラスの記述が不正確で、堅牢性が十分でないことが原因で発生します (例: 解放する必要がある接続が長期間解放されていないなど)
2 例外ハンドラ
2.2.1 例外ハンドラの作成
@RestControllerAdvice //用于标识当前类为REST风格对应的异常处理器
public class ProjectExceptionAdvice {
//统一处理所有的Exception异常
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception ex){
return new Result(666,null);
}
}
例外ハンドラーを使用した場合の影響
2.2.2 @RestControllerAdvice アノテーションの概要
-
名前: @RestControllerAdvice
-
タイプ:クラスアノテーション
-
位置: Rest スタイル開発のコントローラー拡張クラス定義の上
-
役割: Rest スタイルで開発されたコントローラー クラスを強化する
-
説明: このアノテーションには、対応する機能を持つ @ResponseBody アノテーションと @Component アノテーションが付属しています
2.2.3 @ExceptionHandler アノテーションの概要
- 名前: @ExceptionHandler
- タイプ:メソッドのアノテーション
- 場所: 例外処理専用のコントローラー メソッドの上
- 機能: 指定された例外の処理計画を設定します。この機能はコントローラのメソッドに相当します。例外が発生すると、元のコントローラの実行が終了し、現在のメソッドに転送されて実行されます。
- 説明: このメソッドは、処理される例外に応じて、対応する例外を処理する複数のメソッドを作成できます。
4. プロジェクト例外処理計画
問題のインポート
プロジェクトの現在の例外の分類と、該当する例外の種類に対処する方法を教えてください。
1 項目の異常分類
- ビジネス例外 (BusinessException)
- ユーザーの規範的な行動によって生じる異常
- ユーザーのイレギュラーな行動操作による異常
- システム例外 (SystemException)
- プロジェクト運営中の予測可能かつ避けられない例外
- その他の例外(例外)
- プログラマが予期しなかった例外
2 プロジェクト例外処理スキーム
- ビジネス例外 (BusinessException)
- 対応するメッセージをユーザーに送信して標準操作を思い出させます
- システム例外 (SystemException)
- ユーザーを安心させるためにユーザーに定型メッセージを送信する
- 保守を思い出させるために、運用および保守担当者に特定のメッセージを送信します。
- ログを記録する
- その他の例外(例外)
- ユーザーを安心させるためにユーザーに定型メッセージを送信する
- メンテナンスを促す特定のメッセージをプログラマに送信する(想定範囲内に含まれる)
- ログを記録する
3 プロジェクトの例外処理コードの実装
3.1 例外分類に基づいて例外クラスをカスタマイズする
3.1.1 カスタム プロジェクトのシステムレベルの例外
//自定义异常处理器,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
3.1.2 カスタム プロジェクトのビジネス レベルの例外
//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code,String message,Throwable cause) {
super(message, cause);
this.code = code;
}
}
3.2 カスタム例外コーディング (継続的な補足)
public class Code {
//之前其他状态码省略没写,以下是新补充的状态码,可以根据需要自己补充
public static final Integer SYSTEM_ERR = 50001;
public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
public static final Integer SYSTEM_UNKNOW_ERR = 59999;
public static final Integer BUSINESS_ERR = 60002;
}
3.3 カスタム例外をトリガーする
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
//在getById演示触发异常,其他方法省略没有写进来
public Book getById(Integer id) {
//模拟业务异常,包装成自定义异常
if(id <0){
throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
}
}
}
3.4 例外通知クラスでの例外のインターセプトと処理
@RestControllerAdvice //用于标识当前类为REST风格对应的异常处理器
public class ProjectExceptionAdvice {
//@ExceptionHandler用于设置当前处理器类对应的异常类型
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),null,ex.getMessage());
}
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
}
}
テスト: postman の getById メソッドにアクセスするリクエストを送信し、パラメーター -1 を渡すと、次の結果が得られます。