フォームが送信されると、コントローラはフロントエンドから受信したパラメータを確認する必要があり、各パラメータが煩雑である手動で決定された場合、フレームは、検証パラメータの検証を簡素化するために使用することができます
はじめに依存
<! - JSR303パラメータチェックスタート- > <依存> <groupIdを> org.springframework.boot </ groupIdを> <たartifactId>スターター・春ブーツ・バリデーション</たartifactId> </依存関係> <! - JSR303パラメータは終わりをチェック- >
レイヤ2制御パラメータ有効な追加注釈の方法
@RequestMapping(" / do_login " ) @ResponseBody 公共結果の<string> doLogin(HttpServletResponseの応答、@Valid LoginVo loginVo){ log.info(loginVo.toString())。 // 登录 文字列トークン= userService.login(応答、loginVo)。 リターンResult.success(トークン)。 }
カプセル化POJOのためのリクエストパラメータ
ここNOTNULLは、ノートに付属しているフレームワークですIsMobileカスタム注釈
パブリック クラスLoginVo { @NotNull @IsMobile プライベート文字列のモバイル; @NotNull @Length(MIN = 6、最大= 16、メッセージ= " 密码长度错误" ) プライベート文字列のパスワード。 パブリック文字列getMobile(){ 戻りモバイル; } 公共 ボイドsetMobile(文字列モバイル){ この .mobile = 携帯。 } パブリック文字列getPasswordに(){ 戻りパスワード。 } パブリック ボイドするsetPassword(文字列のパスワード){ このみましょう。パスワード= パスワード。 } @Override パブリック文字列のtoString(){ リターン " LoginVo [モバイル= " +モバイル+ " パスワード= " +パスワード+ " ] " 。 } }
次のようにカスタムアノテーションをインストールします。
@Target({メソッド、フィールド、ANNOTATION_TYPEコンストラクタ、PARAMETER}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {IsMobileValidator。クラス}) パブリック@interface IsMobile { ブール必須()デフォルト はtrue 。 文字列のメッセージ()デフォルト " 手机号码格式错误" 。 クラス <?> []グループ()デフォルト{}。 クラス <?延びペイロード> []ペイロード()デフォルト{}。 }
パブリック クラス IsMobileValidator実装ConstraintValidator <IsMobile、文字列> { プライベートブール値が必要= 偽を; 公共 ボイドイニシャライズ(IsMobile constraintAnnotation){ 必要 = constraintAnnotation.required()。 } パブリックブールのisValid(String値、ConstraintValidatorContextコンテキスト){ 場合(必須){ 戻りValidatorUtil.isMobile(値)。 } 他{ 場合(StringUtils.isEmpty(値)){ 戻り 真。 }他{ 戻りValidatorUtil.isMobile(値)。 } } } }
3グローバル例外がキャッチ
パブリック クラスGlobalExceptionはのRuntimeExceptionを拡張{ プライベート 静的最終長いのserialVersionUID = 1L 。 プライベートCodeMsgセンチ。 公共GlobalException(CodeMsg CM){ スーパー(cm.toString())。 この .CM = センチメートル; } 公共CodeMsg getCm(){ 戻りCM。 } }
@ControllerAdvice @ResponseBody パブリック クラスGlobalExceptionHandler { (値@ExceptionHandler =例外クラス) パブリック結果の<string> exceptionHandlerの(HttpServletRequestの要求、例外e){ e.printStackTrace(); もし(E instanceofのGlobalException){ GlobalException EX = (GlobalException)E。 リターンResult.error(ex.getCm()); } そう であれば(はBindExceptionのinstanceof E){ はBindException EX = (はBindException)E。 リスト<ObjectError>誤差= ex.getAllErrors()。 ObjectErrorエラー =エラー。取得(0 ); ストリングMSG = error.getDefaultMessage()。 リターンResult.error(CodeMsg.BIND_ERROR.fillArgs(MSG)); } 他{ リターンResult.error(CodeMsg.SERVER_ERROR)。 } } }
4サービス層アプローチ
公共の文字列のログイン(HttpServletResponseの応答、LoginVo loginVo){ 場合(loginVo == nullの){ スロー 新しいGlobalException(CodeMsg.SERVER_ERROR)。 } モバイルストリング = loginVo.getMobile()。 ストリングformPass = loginVo.getPassword()。 // 判断手机号是否存在 MiaoshaUserユーザー= getById(Long.parseLong(モバイル))。 場合(ユーザー== nullが){ スロー 新しいGlobalException(CodeMsg.MOBILE_NOT_EXISTを)。 } // 验证密码 ストリングDBPASS = user.getPassword()。 ストリングsaltDB = user.getSalt()。 ストリングcalcPass = MD5Util.formPassToDBPass(formPass、saltDB)。 もし(!のcalcPass.equals(DBPASS)){ スロー 新しいGlobalException(CodeMsg.PASSWORD_ERRORを)。 } // 生成クッキー 文字列トークン= UUIDUtil.uuid()。 addCookie(応答、トークン、ユーザ)。 返すトークン; }
5 JSONのフロントエンドに返されます
パブリック クラス結果<T> { プライベート int型のコード; プライベート文字列MSG; プライベートTのデータは、 / * * *成功したときにコール * * / パブリック 静的 <T>結果<T> 成功(Tデータ){ 返す 新しい新しい検索結果を<T > (データ); } / * * *失敗した通話時間 * * / パブリック 静的 <T>結果<T> エラー(codeMsg codeMsg){ 戻り 新しい新しい <T>の検索結果を(codeMsg); } プライベート結果(Tデータ){ この .DATAは= データを、 } プライベート結果(INT コード、文字列MSG){ この .CODE = コード。 この .MSG = MSG; } プライベート結果(CodeMsg codeMsg){ 場合(codeMsg =!ヌル){ この .CODE = codeMsg.getCode(); この .MSG = codeMsg.getMsg()。 } } 公共 のint にgetCode(){ 戻りコードと } 公共 のボイドSETCODE(int型コード){ この .CODE = コード。 } パブリック文字列GETMSG(){ 戻りMSG。 } 公共 ボイドsetMsg(文字列MSG){ この .MSG = MSG。 } パブリックTのgetData(){ 戻りデータ; } 公共 ボイドのsetData(Tデータ){ この .DATA = データ。 } }
利点は、長いようなパラメータがそれを確認するために注釈を追加することです。例外をスローしないことにより、パラメータの検証は、例外ハンドラは、エラーメッセージがフロントエンドに直接返され、捕獲されます。
そして、グローバルな例外ハンドラは、カスタム例外をキャプチャします。