Validatedアノテーションの説明、Grouped Validation、Nested Validation、@Validと@Validatedの違い、Spring Boot @Validated
テクノロジースタック
スプリングブート2.3.3.RELEASE
ハイバーネートバリデーター
プロジェクトのソースコードは、この記事の最後に添付されています。
ディレクトリ
簡単な説明
Validationは、転送されたパラメータのデータを検証し続けるためのアノテーションのセットで、Validationを設定することで簡単に行うことができます。
クラス、メソッド、パラメータに作用する @Validated
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Validated { Class<? >[] value() default {}; }
エラーステータスコード
返されるレスポンスコードは、400 bad requestを推奨します。
すべてのパラメータコメントの意味
プロジェクトの依存関係
Mavenの依存関係の座標です。
注:デモプロジェクトでは、すべてのエンティティクラスはパッケージのエンティティに、コントロールレイヤーはパッケージのコントローラに含まれています。
グローバル例外処理クラス
注意:例外処理を行わない場合、@Validatedアノテーションに対するデフォルトの例外メッセージは以下のようになります(例)。
2020-09-05 21:48:38.106 WARN 9796 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind. MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String com.example.validateddemo.controller. DemoController.validatedDemo1(com.example.validateddemo.entity.dto.UseDto): [Field error in object 'useDto' on field 'username': rejected value [null]; codes [NotBlank.useDto.username,NotBlank.username,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework. context.support.DefaultMessageSourceResolvable: codes [useDto.username,username]; arguments []; default message [username]]; default message [username cannot be empty!] ]
そこで、パラメータのチェックサムが失敗したときにスローされる例外を処理するグローバルな例外処理クラスをここで作成し、ログの出力と一緒に処理するようにしました。
package com.example.validateddemo.handler;
import com.example.validateddemo.base.Result;
import com.example.validateddemo.enums.ResultEnum;
import com.example.validateddemo.utils.ResultUtil;
import lombok.extern.slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind;
import org.springframework.web.bind.annotation;
import org.springframework.web.bind.annotation;
import org.springframework.web.bind.annotation;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.List;
List; /**
* @author He Changjie on 2020/9/5
*/
@Slf4j
@ControllerAdvice
public class ValidatedExceptionHandler {
/**
* Handle @Validated parameter validation failure exceptions
* @param exception exception class
* @return response
*/
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result exceptionHandler(MethodArgumentNotValidException exception){
BindingResult result = exception.getBindingResult();
StringBuilder stringBuilder = new StringBuilder();
if (result.hasErrors()) {
List<ObjectErrors> errors = result.getAllErrors();
if (errors ! = null) {
errors.forEach(p -> {
FieldError fieldError = (FieldError) p;
log.warn("Bad Request Parameters: dto entity [{}],field [{}],message [{}]",fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
stringBuilder.append(fieldError.getDefaultMessage());
});
}
}
return ResultUtil.validatedException(stringBuilder.toString());
}
}
ベースパラメーターチェックサム
エンティティクラス
package com.example.validateddemo.entity.dto;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.*;
/**
* User entity
* Data transfer object
* @author He Changjie on 2020/9/5
*/
@Data
public class User1Dto {
/**
* User name
*/
@NotBlank(message = "User name cannot be empty! ")
private String username;
/**
* Gender
*/
@NotBlank(message = "Gender cannot be empty! ")
private String gender;
/**
* Age
*/
@Min(value = 1, message = "Age is wrong! ")
@Max(value = 120, message = "Age is wrong! ")
private int age
制御クラス
package com.example.validateddemo.controller;
import com.example.validateddemo.entity.dto.Use1Dto;
import org.springframework.validation.annotation.Validated;
importieren org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
importieren org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/**
* @Autor He Changjie am 2020/9/5
*/
@RestController
@RequestMapping("/api/v1")
public class Demo1Controller {
@PostMapping("/insert")
public String validatedDemo1(@Validated @RequestBody Use1Dto use1Dto){
System.out.println(use1Dto);
return "success";
}
}
テスト
1. パラメータ・キャリブレーションに合格
2. パラメータのチェックサムに失敗しました。
ネストしたパラメータの検証
検証する必要があるエンティティ内のオブジェクトのセットや他のオブジェクトを検証する
エンティティクラス
package com.example.validateddemo.entity.dto;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.util.List; import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 队伍实体
* 数据传输对象
* @Autor He Changjie am 2020/9/5
*/
@Daten
public class Team1Dto {
/**
* 队伍名称
*/
@NotBlank(message = "队伍名称不能为空!")
private String name;
/**
* 队伍人员
*/
@NotNull(message = "队伍人员不能为空!")
@Gültig
private List<User1Dto> userList;
/**
* 队伍负责人
*/
@NotNull(message = "队伍负责人不能为空!")
@Gültig
private User1Dto user;
}
制御クラス
package com.example.validateddemo.controller;
import com.example.validateddemo.base.Result;
import com.example.validateddemo.entity.dto.Team1Dto;
importieren com.example.validateddemo.entity.dto.Use1Dto;
importieren com.example.validateddemo.utils.ResultUtil;
import org.springframework.validation.annotation.Validated;
importieren org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
importieren org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/**
* @Autor He Changjie am 2020/9/5
*/
@RestController
@RequestMapping("/api/v1")
public class Demo1Controller {
@PostMapping("/insert")
public Result validatedDemo1(@Validated @RequestBody Use1Dto use1Dto){
return ResultUtil.success(use1Dto);
}
@PostMapping("/insert2")
public Result validatedDemo2(@Validated @RequestBody Team1Dto team1Dto){
return ResultUtil.success(team1Dto);
}
}
テスト
1. パラメータのバリデーションに合格した。
2. パラメータバリデーションが通らない。
グループ化されたパラメータ検証
異なる検証ルールをグループ化し、使用時に異なる検証ルールを指定することができる
インターフェースクラス
package com.example.validateddemo.interfaces;
/**
* 校验分组1
* @author He Changjie am 2020/9/5
*/
public interface Gruppe1 {
}
package com.example.validateddemo.interfaces;
/**
* 校验分组2
* @author He Changjie am 2020/9/5
*/
öffentliche Schnittstelle Group2 {
}
エンティティクラス
package com.example.validateddemo.entity.dto;
import com.example.validateddemo.interfaces.Group1;
import com.example.validateddemo.interfaces.Group2;
import lombok.Data;
import javax.validation.constraints.*;
/**
* @author He Changjie am 2020/9/5
*/
@Data
public class User2Dto {
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空!", groups = {Group1.class})
private String username;
/**
* 性别.
*/
@NotBlank(message = "性别不能为空!")
private String gender;
/**
* 年龄
*/
@Min(value = 1, message = "年龄有误!", groups = {Group1.class})
@Max(Wert = 120, Nachricht = "年龄有误!", Gruppen = {Group2.class})
private int age;
/**
* 地址.
*/
@NotBlank(message = "地址不能为空!")
private String-Adresse;
/**
* 邮箱
*/
@Email(message = "邮箱有误!", groups = {Group2.class})
private String email;
/**
* 手机号码
*/
@Pattern(regexp = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$",message = "手机号码有误!", groups = {Group2.class})
private String mobile;
}
制御クラス
package com.example.validateddemo.controller;
import com.example.validateddemo.base.Result;
import com.example.validateddemo.entity.dto.Team1Dto;
import com.example.validateddemo.entity.dto.User1Dto;
import com.example.validateddemo.entity.dto.User2Dto;
import com.example.validateddemo.interfaces.Group1;
import com.example.validateddemo.interfaces.Group2;
import com.example.validateddemo.utils.ResultUtil;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation;
import org.springframework.web.bind.annotation;
import org.springframework.web.bind.annotation;
/**RequestMapping; import org.springframework.web.bind.annotation.
* @author He Changjie on 2020/9/5
*/
@RestController
@RequestMapping("/api/v1")
public class Demo1Controller {
@PostMapping("/insert")
public Result validatedDemo1(@Validated @RequestBody User1Dto user1Dto){
return ResultUtil.success(user1Dto);
}
@PostMapping("/insert2")
public Result validatedDemo2(@Validated @RequestBody Team1Dto team1Dto){
return ResultUtil.success(team1Dto);
}
@PostMapping("/insert3")
public Result validatedDemo3(@Validated @RequestBody User2Dto user2Dto){
return ResultUtil.success(user2Dto);
}
@PostMapping("/insert4")
public Result validatedDemo4(@Validated(Group1.class) @RequestBody User2Dto user2Dto){
return ResultUtil.success(user2Dto);
}
@PostMapping("/insert5")
public Result validatedDemo5(@Validated(Group2.class) @RequestBody User2Dto user2Dto){
return ResultUtil.success(user2Dto);
}
}
テスト
1. グループ化されていないチェックサムが通過する。
2. グループ化されていないパラメータのチェックサムが通らない。
3. グループ1パラメータがチェックアウトされる
4. グループ 1 パラメータのチェックサムが通らない
5. グループ化された2つのパラメータチェックが通過
6. グループ化 2 パラメータのチェックサムが通らない
7. デフォルトのグループ化を使用すると、パラメータのチェックサムは通過します。
注:以下のように調整した後、コントロールレイヤー/insert3インターフェイスをテストしてください。
@PostMapping("/insert3")
public Result validatedDemo3(@Validated(Default.class) @RequestBody User2Dto user2Dto){
return ResultUtil.success(user2Dto);
}
Default.classはValidated依存関係に含まれるインターフェースクラスであり、カスタムインターフェースクラスではありません。
8. デフォルトのグループ化を使用すると、パラメータのチェックサムが通らない。
説明 ポイント7と同じ操作
Validと@Validatedの違いについて
ソースコードによる解析。
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Valid {
}
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
Class<? >[] value() default {};
}
@Valid です。グループ化されていません。
有効:メソッド、コンストラクタ、メソッドパラメータ、メンバプロパティ(フィールド)に使用できる。
Validated: グループ化機能を提供し、受信した検証時に異なる検証メカニズムを異なるグループに適用することができます。
Validated: 型、メソッド、メソッド・パラメータに使用できます。ただし、メンバープロパティ(フィールド)には使用できない。
メンバープロパティ(フィールド)で両方を使用できることは、ネストされたバリデーションを提供する能力に直接影響します。
コードクラウドのアドレスです。 https://gitee.com/jie_harris/validateddemo.git
手作業での編集は難しいので、出典を明記してください。
ありがとうございます。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例