例外処理でSpringBoot-最適化プロジェクト

1.0なぜ私たちは例外が必要なのか

Javaの例外について、あなたは私がブログに書いた前に参照することができ、システムの異常やプロジェクトの使用- Javaの基礎(8)異常な思考とどのように例外を使用すると呼ばそのうちのいくつかを、。

なぜ我々はそれが異常な必要なのでしょうか?

私たちは三つの異なる角度からおよそ考えることができると思います。

  1. バックエンドの開発者:すぐにプログラムに、と解決の問題にログインすることで、どこに問題を見つけるために、バックエンドの開発を行います。
  2. フロントエンドの開発者は:例外のタイプに応じて、適切なスタイルのショーを行います
  3. ユーザー:えーえー?ユーザーは技術を理解していない、あなただけのテキストまたはグラフィックプロンプトで例外の種類を知る必要はありません。

例えば、CSDNのアップロードは、プロンプトAのネットワークエラーが、ネットワークの私の側には何の問題もありませんファイルが、私たちが間違ったネットワークアイデンティティに投げるので、忙しいか、内部サーバーエラーです。
ここに画像を挿入説明

1.1 1.0例外処理

したがって、リアとフロントエンドの間に全体の異常、バックエンドが例外をスローし、フロントニーズが例外に基づいてユーザに提示別のページを表示するには、これは例外処理の最も基本的な方法は以下のとおりです。

ここに画像を挿入説明

2.0の取り扱い1.2例外

1.0モードでは、本質的に捕獲及び変換の異常な先端によって、しかし異常なバックエンドによって生成されたので、次に最も正しいアプローチは、例外処理方法の一部を引き出されており、後端部によって処理されます。現在の方法は、簡単な実装ステータスコードの代わりに、例外を使用することです。

表示ステータスコードに応じてフロントエンド処理に対応し、異常な状態コードに取り込まれ、処理の後端の例外:

ここに画像を挿入説明

この利点は、次のとおりです。

1.安全な、具体的な情報が異常を公開するために行われません、バックエンドの例外処理を行います
。2.フロントエンドのみ、追加の例外を必要とせずに、状態コードに対応するページジャンプ予定のバックエンドに基づいて行うことができますプロセスは、のみ正しく各側論理の各端部をハンドル高い凝集力、低い結合の目標を達成することができます。

第一の実施形態の処理1.3例外

最初の方法は、次に、ケースの少数の珍しいコントローラ層内に捕捉され、処理された、サービス層においてのみ可能異常が例外をスローする場合、非常に簡単で粗あります。

プロジェクトSpringBoot / SSMで例外処理を使用する方法についてのタッチにテンプレートメッセージモジュールと関連して以下、思考プロセスは、サービス層にスローされた例外、およびコントローラ異常なキャプチャで統一する層であり、処理します:

  • ArgsLoseException
/**
 * @Auther: ARong
 * @Description: 参数缺失异常
 **/
public class ArgsLoseException extends Exception {
    public ArgsLoseException(){}
    public ArgsLoseException(String message){super(message);}
}
  • ArgsErrorException
/**
 * @Auther: ARong
 * @Description: 参数错误异常
 **/
public class ArgsErrorException extends Exception {
    public ArgsErrorException() {}
    public ArgsErrorException(String messasge) {super(messasge);}
}
  • TemplateMessageSerivceImp
/**
 * @Auther: ARong
 * @Description: 发送模板消息
 **/
@Service
@Transactional
@Slf4j
public class TemplateMessageSerivceImp implements TemplateMessageSerivce {
    @Autowired
    private MessageUtil messageUtil;
/**
     * @param messageEntity
     * @param opeType
     * @auther: Arong
     * @description: 注册成功后发送
     * @param: [messageEntity]
     * @return: AjaxResult
     */
    @Override
    public AjaxResult sendMessage(MessageEntity messageEntity, String opeType) throws ArgsLoseException, ArgsErrorException { 
        Map map = MessageUtil.MessageMap(
                messageEntity.getOpenId(),
                messageEntity.getPage(),
                messageEntity.getFormId()
        );

        if (opeType == null || "".equals(opeType.trim())) {
            throw new ArgsLoseException("opeType参数缺失");
        }

        if (!"YES".equals(opeType)) {
            throw new ArgsErrorException("opeType参数错误");
        }

        //...业务逻辑
        return null;
    }
  }

私たちは注目し、この時点では、コントローラ層が行うこれらの例外を処理する方法をすべきですか?

まず、私たちは、例外は、ステータスコードに応じて操作するユーザに促すために、例えば、適切な治療を行うためのフロントエンドが間違っているように、直接フロントエンドのコードの種類にユーザーの目にではなく、異常な状態にさらされることは許されるべきではないことに注意する必要があります、又はそのユーザの目に状態異常に短い焦点状態コード規則前後端におけるネットワーク遅延、等:

  • TemplateMessageController
@Controller
@CrossOrigin
@RequestMapping(value = "/message")
@ResponseBody
@Slf4j
public class TemplateMessageController {
    @Autowired
    private TemplateMessageSerivce templateMessageSerivce;

    /**
     * @auther: Arong
     * @description: 注册成功后发送
     * @param: [messageEntity]
     * @return: AjaxResult
     */
    @PostMapping(value = "/sendMessage")
    public AjaxResult sendMessage(
            @ModelAttribute MessageEntity messageEntity,
            @RequestParam(name = "opeType") String opeType //操作类型
    ) {
        AjaxResult ajaxResult = null;
        try {
            ajaxResult = templateMessageSerivce.sendMessage(messageEntity, opeType);
        } catch (Exception e) {
            //打印异常栈堆路径
            e.printStackTrace();
            //分不同异常给前端返回不同的状态码(不要将异常暴露给前端,而是通过状态码让前端去反应)
            if (e instanceof ArgsLoseException) {
            	//回传状态码501
                return new AjaxResult(501, "传入opeType为空");
            } else if (e instanceof ArgsErrorException) {
            	//回传状态码502
                return new AjaxResult(502, "参数错误");
            }
        }
        return ajaxResult;
    }}

この例外は良い十分なされているときに、非常に少数の例外に対処するためのカスタムの方法で処理することはなく、下記のように、より多くのカスタム例外として、あなたはより多くの異常なコントローラに対処する必要があります。


			if (e instanceof ArgsLoseException) {
            	//回传状态码501
                return new AjaxResult(501, "传入opeType为空");
            } else if (e instanceof ArgsErrorException) {
            	//回传状态码502
                return new AjaxResult(502, "参数错误");
            } else if (e instanceof Xx1Exception) {
            	//...
			} else if (e instanceof Xx2Exception) {
            	//...
			} else if (e instanceof Xx3Exception) {
            	//...
			}

だから、道の例外処理を最適化するために、次の必要性

第二の方法の取り扱い1.4例外 - グローバル例外ハンドラ

上記過剰場合は他の問題を例外処理、および組み込まれた例外処理コードが簡略化され、本明細書SpringBootグローバル例外処理を最適化するために、以下では、特定のサービス・モジュールに関連していないデモプログラムは、それは単なる例示です。

  • AjaxResultリターン結果
/**
 * @Auther: ARong
 * @Description: 处理结果
 */
@Data
public class AjaxResult {
    public AjaxResult() {
    }

    public AjaxResult(int code, String message) {
        this.code = code;
        this.message = message;
    }

    private int code;
    private String message;
}
  • GlobalExceptionグローバル例外、内部の内部クラスは、カスタム例外を定義します
/**
 * @Auther: ARong
 * @Description: 全局异常定义
 */
public class GlobalException {
    /*
     * @Author ARong
     * @Description 参数缺少异常
     **/
    @Data
    public static class ArgsLoseException extends RuntimeException{
        private int code = 501;
        private String message;

        public ArgsLoseException(String message) {
            this.message = message;
        }
    }

    /*
     * @Author ARong
     * @Description 参数错误异常
     **/
    @Data
    public static class ArgsErrorException extends RuntimeException{
        private int code = 502;
        private String message;

        public ArgsErrorException(String message) {
            this.message = message;
        }
    }
}
  • GlobalExceptionHandler
    使用@ControllerAdviceと@ExceptionHandlerグローバル例外ハンドラを達成
/**
 * @Auther: ARong
 * @Description: 全局异常处理器
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /*
     * @Author ARong
     * @Description 捕捉异常并进行处理
     * @Param
     * @return
     **/
    @ExceptionHandler(value = Exception.class)
    public AjaxResult exceptionHandler(Exception e) {
        // 打印异常调用栈
        e.printStackTrace();
        AjaxResult result = new AjaxResult();

        int code = 500;
        String message = "服务器出现错误";

        // 如果是自定义异常则进行转化
        if (e instanceof GlobalException.ArgsErrorException) {
            // 参数错误异常
             code = ((GlobalException.ArgsErrorException) e).getCode();
             message = ((GlobalException.ArgsErrorException) e).getMessage();
        }
        if (e instanceof GlobalException.ArgsLoseException) {
            // 参数缺失异常
            code = ((GlobalException.ArgsLoseException) e).getCode();
            message = ((GlobalException.ArgsLoseException) e).getMessage();
        }

        result.setCode(code);
        result.setMessage(message);
        return result;
    }
}
  • DemoController制御層
/**
 * @Auther: ARong
 * @Description: 控制层
 */
@Controller
@ResponseBody
public class DemoController {
    @Autowired
    private DemoService demoService;

    @RequestMapping(value = "/get")
    public AjaxResult get(
            @RequestParam(name = "id") String id
    ) {
        AjaxResult result = demoService.get(id);
        return result;
    }
}
  • DemoServiceビジネス層
/**
 * @Auther: ARong
 * @Description: 业务层
 */
@Service
public class DemoService {
    public AjaxResult get(String id) {
        if ("bug".equals(id)) {
            // 参数错误
            throw new GlobalException.ArgsErrorException("参数错误");
        }
        if ("null".equals(id)) {
            // 参数缺失
            throw new GlobalException.ArgsLoseException("参数缺失");
        }
        return new AjaxResult(200, "OK");
    }
}

グローバル例外ハンドラ、キャプチャする必要性にコントローラ層とカスタム例外を処理し、すべてに対応する処理を行うと、ステータスコードを返すようにプロセッサを設定した後。郵便配達の簡単なテストを使用して、プロジェクトを開始します。

  1. 正常に

ここに画像を挿入説明

  1. トリガーパラメータエラー例外
    ここに画像を挿入説明

  2. トリガー異常なパラメータが不足しています
    ここに画像を挿入説明

上記の手順の後、あなたはプログラムの可読性を向上させるために、大幅に簡略化する基本的なグローバル例外ハンドラ、および冗長性の少ない符号量コントローラ層を達成することができ、より重要なことの残りの部分は、合意がコードを明記してください方法ですどのようにフロントエンドとジャンプを行います。

感謝

https://blog.csdn.net/Colton_Null/article/details/84592748

309元記事公開 ウォンの賞賛205 ビューに30万+を

おすすめ

転載: blog.csdn.net/pbrlovejava/article/details/104077976