パケットガイドと構成
JSR 303パッケージをインポートし、有効なパッケージを冬眠します
<依存関係> groupId> org.hibernate.validator </groupid> <artifactid> hibernate-validator </artifactid> <version> 6.0.5.final </version> </dependency> <seplency> <グループ<バージョン> 2.0.0.ファイナル</version> </dependency>
スプリングブート構成
リソース/application.ymlメッセージリソースファイル国際処理構成
春:
メッセージ:
Basename:ベース、TODO#リソースファイルBase.Properties and Todo.Properties、コンマで区切られた
エンコーディング:UTF-8#解析エンコードを指定する必要があります。
Springboot Startupクラスで構成します
@SpringBootApplicationPublic Class Applications extends webmvcconfigureradapter {@value( "$ {spring.messages.basename}")private string basename; public static void main(string [] args){springapplication.run(application.class、args); } @bean @primary public messagessource messagesource(){resourcebundlemessagesource resourcebundlemessagesource = new ResourceBundleMessageSource(); ResourceBundleMessageSource.setUseCodeasDefaultMessage(false); ResourceBundleMessageSource.setDefaultEncoding( "utf-8"); //定義を繰り返すResourceBundleMessagesOurce.setBasenames(basename.split( "、")); ResourceBundLemessagesOurceを返します。 } @bean @primary public localvalidatorfactorybean validator(){localvalidatorfactorybean validatorfactorybean = new localvalidatorfactorybean(); validatorfactorybean.setproviderclass(hibernatevalidator.class); validatorfactorybean.setValidationMessageSource(messageSource()); return validatorfactorybean; } @Override public validator getValidator(){return validator(); } / ***メソッドレベルでの単一パラメーター検証が有効になります* / @bean publicvalidationpostprocessor methodvalidationpostprocessor(){return new MethodValidationPostProcessor(); }}検証パラメーターを渡すことができず、統一された例外キャプチャを介したスローを渡すことができない例外を処理します。
@controlleradvice @componentPublic class bindvalidexceptionhandler { @responsestatus(value = httpstatus.ok)@exceptionhandler(constraintviolationexception.class)public @responsebody msg handleconstraintviolationexception(constraintviolationexception {sinstraintviolationexception {String stringeTemplate = e.getConstraintViolations()。iterator()。next()。getMessagetEmplate(); return msg.error(messagetemplate); } @responsestatus(value = httpstatus.ok)@exceptionhandler(bindexception.class)public @responsebody msg handlebindexception(bindexception e){bindingResult bindingResult = e.getBindingResult(); string classname = bindingResult.getTarget()。getClass()。getName(); fielderror next = bindingResult.getFielderRors()。iterator()。next(); string fieldname = next.getfield();文字列defaultmessage = next.getDefaultMessage(); if(pattern.compile( "IllegalargumentException:no enum") if(matcher.find()){defaultmessage = "enumタイプは見つかりません[" + matcher.group(1) + "]"; }} return msg.error(defaultmessage); } @responsestatus(value = httpstatus.ok)@exceptionhandler(validerror.class)public @responsebody msg handlevaliderror(validerror e){return msg.error(e.getmessage()); }}リソース/base.propertie
creatorid = creatorIDは{value}未満にすることはできません。
ModifierID = Modifier IDは{値}未満にすることはできません。
リソース/TODO.Properties
todo.privateid.min = private idは{value}未満にすることはできません。
グループ内のcとsのインターフェイスは、すべてのカスタムコンベンションである挿入インターフェイス、更新インターフェイスなどを含むコントローラーとサービスの略語を指します。
/***プライベートIDは、プロジェクトタスク/非プロジェクトタスク/リスク/リスク/問題の質問/問題の質問/@min(value = 1、message = "{todo.privateid.min}などの複数のテーブルを表す外部キーです。 */@min(value = 1、message = "{creatorid}"、groups = {s.insert.class})private long creatorid; controllerコントロールレイヤー検証@validated@restcontroller@requestmapping( "dodo")パブリッククラスのtodocontroller {@autowired private doservice todoservice; @getMapping( "getvo")public msg getvo(@min(value = 1、message = "do do idは1未満ではありません)@RequestParam(必須= false、default、default =" 0 ")long id){this.todoservice.getvo(id); } @postmapping( "add")public msg add(@validated({c.insert.class})todo todo){this.todoservice.add(todo); }}@validated({c.insert.class})は、Bean Annotationで検証グループを有効にすることを宣言し、他の検証グループは検証を実行しません。
たとえば、エンティティがなく、1つの基本データ型のみがある場合は、検証できますが、3つの条件を満たす必要があります。
自分で確認してください。
サービスサービスレイヤーAOP検証
validutilツールクラス
スプリングブートで1つのケースとしてスキャンして登録する必要があります
@componentPublic class validutil {@autowired private validator validator; public <t> set <constraintviolation <t >> validate(t object、class <?> ... groups){return validator.validate(object、groups); } public <t> set <constraintviolation <t >> validateValue(class <t> beantype、string propertyname、object value、class <? } / ***パラメーターを検証して最初のエラープロンプトを返します* @param t verified object* @paramグループ検証済みグループ* @param <t>オブジェクト消去の前に* @return最初のエラープロンプト* / public valid balid andreturnfirsterrortips(t t、class <? if(validate.size()> 0){constraintviolation <t> next = validate.iterator()。next(); string message = next.getRootbeanClass()。getName() + " - " + next.getPropertyPath() + " - " + next.getMessage();新しいvaliderror(メッセージ)を投げる; }} / ***パラメーターを確認し、最初のエラープロンプトを返します* @paramターゲットクラス検証されたオブジェクトのクラスタイプ* @param objプロパティ値が必要な@param objプロパティ値が必要です* @paramグループグループ検証グループ* @param <>オブジェクト消去の前に元のタイプ* @returnエラー* obj、class <? if(validate.size()> 0){string message = targetclass.getName() + " - " + fieldName + " - " + validate.iterator()。next()。getMessage();新しいvaliderror(メッセージ)を投げる; }}}AOP構成
主な原則は、AOPインターセプトメソッドを使用してパラメーターを実行し、パラメーターの注釈を取得することです。次に、ツールクラスを使用してパラメーターを確認します。検証が失敗した場合、カスタムエラーが直接スローされ、カスタムエラーがグローバルに処理されます。
@Aspect @componentPublic class validatorAop {@autowired private validutil validutil; /***インターセプトルールの定義:com.Serviceパッケージの下のすべてのクラスを傍受すると、@Service Annotationのメソッドがあります。 */ @pointCut( "execution(*com.service ..*(..))および@Annotation(org.springframework.stereotype.service)")public void controllermethodpointcut(){}/ ***interceptor*/ @around( "controllmethodpoint()")/ @Around()また、「execution(* com.xjj ........)」をこのパブリックオブジェクトインターセプター(ProceedingJoinPoint PJP)に直接記述することもできます。メソッドmethod = methodignature.getMethod(); annotation [] [] argannotations = method.getParameterAnnotations(); object [] args = pjp.getargs(); for(int i = 0; i <args.length; i ++){for(annotation annotation:argannotations [i]){if(validated.class.isInstance(annotation)){validated validated =(validated)annotation; class <? validutil.validandreturnfirsterrortips(args [i]、グループ); }} try {pjp.proceed(args); } catch(throwable throwable){throwable.printstacktrace(); } trueを返します。 }}annotation @min @notnull usageメソッドを確認します
実装クラスに書くことはできません。インターフェイスでは注釈だけを使用できます
基本的にコントローラーと同じ方法
@validatedPublic Interface todoservice { / *** query single to-do* @param id serial number* @return single to-do* / msg getvo(value = 1、message = "to-do idは1未満ではありません)。 / ***データの追加* @param Todo Object*/ msg add(@validated({s.insert.class})todo todo);}いくつかのカスタム検証注釈を共有します
文字列ヌル検証
javax.validation.constraints; Import javax.validation.constraint; Import javax.validation.constraintvalidator; Import javax.validation.constraintalidatorContext; impont javax.validation.payload; import java.lang.Annotation。使用することはできず、書き直す必要があります。パッケージを変更できません。 */@documented@constraint(validatedby = {notblank.notblankvalidator.class})@target({elementType.field、elementType.annotation_type、elementType.parameter})@retention(retentionPolicy.runtime)公開@interface {class <?> string message()default "{notblank}";クラス<?ペイロード> [] payload()default {}; class notblankvalidatorはconstraintvalidator <notblank、object> {public notblankvalidator(){} @override public void initialize(notblank constraintannotation){} @override public boolean isvalid(オブジェクト値、constraintalidatorContext context){return value! }}}タイプが値の1つであるかどうかを判断するために、判断を入力すると、検証グループに基づいて判断をカスタマイズできます
Resources/TODO.PROPERTIESTODO.TODOPIE.INSERT =新しく追加された場合、TO-DOタイプは非プロジェクトタスク、プロジェクトタスク、または問題の1つにすぎません。 todo.todotype.update =変更すると、to-doタイプはリスクの1つであり、To Doの問題を確認できます。 bean/*** todype0non-project task1project task2problem33risk4reviewtodopevalid(value = {"0"、 "1"、 "2"}、message = "{todo.todotype.insert}" = "{todo.todope.update}"、groups = {c.update.class、s.update.class})private string todype;カスタムアノテーション
@documented@constraint(validatedby = {todotypevalid.todotypalidfactory.class})@target({elementType.field、elementType.annotation_type、elementtype.parameter})@retention(retentionPolicy.runtime)@Repeatable(defcorid.list.list.list.list.list.class)@repeatable( 「正しいタイプを入力してください」。 string [] value()default {}; class <?> [] groups()default {};クラス<?ペイロード> [] payload()default {};クラスpodypevalidfactoryは制約validator <todypevalid、string> {private string [] annotationValue; @Override public void initialize(todypevalid todostatusvalid){this.annotationValue = todostatusvalid.value(); } @Override public boolean isvalid(string value、constraintValidatorContextコンテキスト){if(arrays.aslist(annotationValue).Contains(value))return true; falseを返します。 }} @target({elementType.field、elementType.annotation_type、elementType.parameter})@retention(retentionPolicy.runtime)@documented @interface list {todypevalid [] value(); }}@Repeatable(todytotyevevalid.list.class)は、JDK8でサポートされている同じ注釈複数回機能です。
上記によると、列挙クラスでも使用できます。
Resources/TODO.PROPERTITEDODO.TODOSTATUS.INSERT =新しいに追加すると、ステータスは開始できません。 todo.todostatus.update =が変更された場合、ステータスは進行中または完了することのみができます。 Bean/*** Todo Status 0開始1進行中2完了*/@todostatusValid(enums = {todostatus.not_started}、message = "{todo.todostatus.intert}"、groups todostatus.completed}、message = "{todo.todostatus.update}"、groups = {c.update.class、s.update.class})private dodostatus todostatus;カスタムアノテーション
@documented@constraint(validatedby = {todostatusvalid.todostatusvalidfactory.class})@target({elementType.field、elementType.annotation_type、elementType.parameter})@retention(retentionPolicy.runtime)@Repeatable(dodostatasusgalid.list.list.list.list.list.clist.classメッセージ()デフォルト「正しいステータスを入力してください」; todostatus [] enums()default {}; class <?> [] groups()default {};クラス<?ペイロード> [] payload()default {};クラスdodostatusvalidfactoryは制約validator <todostatusvalid、dodostatus> {private todostatus [] enums; @Override public void initialize(todostatusvalid todostatusvalid){this.enums = todostatusvalid.enums(); } @Override public boolean isvalid(todostatus value、constraintvalidatorContext Context){todostatus [] values = todostatus.values(); if(enums!= null && enums.length!= 0){values = enums; } if(arrays.aslist(values).contains(value))trueを返します。 falseを返します。 }} @target({elementType.field、elementType.annotation_type、elementType.parameter})@retention(retentionPolicy.runtime)@documented @interface list {todostatusvalid [] value(); }}要約します
上記は、編集者がSpringbootに導入したもので、JSR 303を使用してコントローラー制御レイヤーとサービスサービスレイヤーAOP検証を検証します。メッセージリソースファイルを使用して、メッセージを国際化します。私はそれが誰にでも役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!