この記事では、検証手順を導入する方法、カスタム検証を通じてコードの量を減らし、生産性を向上させる方法を簡単に紹介します。特別な言及:非プリミティブ型属性の有効、GETメソッドの処理、検証エラーメッセージの統一解像度。
この記事の実際の検証の実装は、処理のための冬眠検証を委託されています
基本的な構成
POMはMaven依存関係を紹介します
<! - 検証Begin-> <dependency> <groupId> javax.validation </groupId> <artifactid> vilatifation-api </artifactid> <バージョン> 1.1.0.ファイナル</version> </dependency> <dependency> org.hibernate </groupid> <artifactid> hibernate-validator </artifactid> <バージョン> 5.4.0.ファイナル</version> </dependency> <! - 検証終了 - >
検証構成を追加します
次の構成をspring-mvc-servlet.xmlに追加します。
<MVC:Annotation-driven validator = "Validator"> <Bean id = "Validator"> <Property name = "propiderClass" value = "org.hibernate.hibernatevalidator"/> <プロパティ= "validationmessagesource" read = "sageSource" // seecurations easion countextext.xxcontext。
カスタム例外ハンドラー
検証エラーメッセージをパーソナライズすると、発信者に返される情報がよりフレンドリーです。次の構成がApplicationContext.xmlに追加されます。
<! - i18nメッセージリソースファイルをロードする - > <bean id = "messageSource"> <プロパティ名= "basenames"> <list> <value> errormsg </value> <balue> validation_error </value> </list> </compropert
プロジェクトClassPathに追加:validation_zh_cn.propertiesリソースファイル:
#入力検証のエラーMSG#COMMON.NOT.BE.NULL = {FIELD}は空のフィールドにはできません。 validationexceptionResovlerの実装:
validationexceptionResovler.java
@slf4jpublic class validationexceptionResovler拡張abstracthandlerexceptionResolver {public validationexceptionResovler(){// Orderを設定して、this.setorder(0); } /** * {@code @valid}でアノテーションされた引数が{@link}や{@link}}引数が検証に失敗した場合を処理します。 * <p> *カスタム検証exception例外ハンドラー *特定の検証エラーメッセージを取得し、CommonResponseを組み立てて発信者に戻ります。 * * @paramリクエスト現在のHTTPリクエスト * @param応答現在のHTTP応答 * @Param Handler実行されたハンドラー * @return例外が処理されたことを示す空のモデルとview * @Throws ioException。リクエスト、httpservletResponse応答、オブジェクトハンドラー)IoException {list <objecterror> errors = bindingResult.getAllerrors(); stringbuffer errmsgbf = new StringBuffer(); for(objecterrorエラー:エラー){string mass = error.getDefaultMessage(); errmsgbf.append(マッサージ); errmsgbf.append( "||"); } string errmsgstring = errmsgbf.toString(); errmsgstring = errmsgstring.length()> 2? errmsgstring.substring(0、errmsgstring.length()-2):errmsgstring; log.Error( "検証に失敗!{}"、errmsgstring); map <string、object> map = new treemap <string、object>(); map.put( "success"、false); map.put( "errorcode"、 "9999"); map.put( "errormsg"、errmsgstring); modelandview mav = new ModelandView(); mappingjackson2jsonView View = new MappingJackson2JSonView(); view.setattributesmap(マップ); mav.setView(表示); mavを返します。 } @Override Protected ModelandView DoreSolveException(httpservletrequest request、httpservletResponse応答、オブジェクトハンドラー、例外Ex){BindingResult BindingResult = null; if(methodArgumentNotValidexception){bindingResult =((methodargumentnotvalidexception)ex).getBindingResult(); } else if(ex instanceof bindexception){bindingResult =((bindexception)ex).getBindingResult(); } else {//その他の例外、無視} if(bindingResult!= null){try {return handlemethodargumentnotvalidexception(bindingResult、request、response、handler); } catch(ioException e){log.Error( "doresolveexception:"、e); }} nullを返します。 }}コントローラーに@validを追加します
@RequestMapping( "/buy")@ResponseBodyPublic Baseresponse Buy(@RequestBody @Valid BuyFlowerRequestリクエスト)スロー例外{// ......}リクエストBeanで検証を必要とする属性に検証注釈を追加する
@setter@getterpublic class buyflowerrequest {@notempty(message = "{name.can.not.be.null}")プライベート文字列名;}二次オブジェクトの検証
上記の書き込み方法は、BuyFlowerRequestの基本型属性のみを検証できますが、オブジェクト属性の属性を検証する方法はありません。セカンダリオブジェクトの属性を検証する必要がある場合は、@validおよび特定の検証アノテーションをセカンダリオブジェクトとセカンダリオブジェクト属性に同時に追加する必要があります。
次の記述方法:
@setter @getterpublic class buyflowerrequest {@notempty(field = "bianname")private string name; @min(field = "price"、value = 1)private int price; @notnull private list <paytype> paytypelist;} @setter @getterpublic class paytype {@valid @min(value = 1)private int paytype; @valid @min(value = 1)private int payamount;}エンコーディングの数をさらに減らします
カスタム検証アノテーションを介して、エンコーディングワークロードを減らすために、ファイルされた検証名をエラーメッセージのリソースファイルに渡すようにして、各ドメインの異なるメッセージテンプレートの記述を避けてください。
これが書き直された@notnullの例です:
1.検証アノテーションを定義し、Field()がNative Annotationに比べて追加されていることに注意してください。これは、検証されたファイル名を渡すために使用されます。
notnull.java
@target({elementType.Method、elementType.field、elementType.annotation_type、elementType.constructor、parameter})@constraint(balidatedby = {notnullvalidator.class})@retention(retentionpolicy.runtime)public@interface not notnull {) string message()default "{field.can.not.be.null}"; class <?> [] groups()default {};クラス<?ペイロードを拡張> []ペイロード()デフォルト{};} 2。バリデーターを定義し、すべてのバリデーターが制約validatorインターフェイスを実装します。
notnullvalidator.java
パブリッククラスnotnullvalidatorは、制約validator <notnull、object> {@override public void initialize(notnull annotation){} @override public boolean isvalid(object str、constraintvalidatorContext constraintatorContext){return str!= null; }} 3.検証アノテーションを追加して、提出するには、提出された価値の指定に注意してください。メッセージにパーソナライズされた要件がない場合は、指定する必要はありません。検証コンポーネントは、デフォルトのメッセージを単独で入力します。
buyflowerrequest.java
@setter @getterpublic class buyflowerrequest {@notempty(field = "bianname")private string name; @min(field = "price"、value = 1)private int price;}注:@notnullアノテーションは、リストの特別な検証を既にサポートしています。リストタイプノードの場合、list == null ||の場合list.size()== 0はfalseを返し、検証が失敗します。現在、@notnull、@notempty、@min、@maxアノテーションは、このアイデアに従ってカスタマイズされており、Goods Projectに記載されています。
GETリクエストをサポートします
上記の例はすべて投稿リクエストです。 @RequestBodyは投稿リクエストを解決できますが、GETリクエストをサポートしていません。 Springのドキュメントとソースコードを読んで、@modelattributeが豆へのリクエストを解決し、検証をサポートできることを発見しました。詳細については、Spring Source Code:ModelAttributeMethodProcessor.ResolVearGument()メソッドを読むことができます。
使用例:
@RequestMapping(value = "/buy"、method = requestmethod.get)@responsebodybaseresponse詳細(@valid @modelattribute detailflowerrequest request)をスロー{detailflowerResponse response = new detailflowerResponse(); Response.setName(request.getName()); runter resultFactory.success(response、baseresponse.class);}トト
1.日付形式、金額など、ビジネスシナリオに従って検証を展開します。
2。複数のフィールド関係検証の検証をサポートします
添付ファイル:Spring検証実装キーコード
@RequestBody
実装クラス:RequestResponseBodyMethodProcessor.java
Public Object Resolveargument(MethodParameterパラメーター、ModelandViewContainer MavContainer、NativeWebRequest WebRequest、WebDataBinderFactory BinderFactory)スロー{Object Arg = this.readwithmessageconverters(this.readwithmessageconverters(webrequest、parameter、parameter.getgenericparametertype());文字列名= Conventions.GetVariaBlenameForParameter(パラメーター); webdatabinder binder = bindfactory.createbinder(webrequest、arg、name); if(arg!= null){this.validateifapplible(binder、parameter); if(binder.getBindingResult()。haserrors()&& this.isbindexceptionRequired(binder、parameter)){throw new MethodArgumentNotValidexcection(parameter、binder.getBindingResult()); }} mavcontainer.addattribute(BindingResult.Model_Key_Prefix + name、binder.getBindingResult()); argを返す;} @modelattuite
実装クラス:modelattributemethodprocessor.java
public final object Resolveargument(MethodParameterパラメーター、ModelandViewContainer mavcontainer、nativewebrequest webrequest、webdatabinderfactory binderfactory)スロー{string name = modelfactory.getNameForParameter(パラメーター); object属性= mavcontainer.containsattribute(name)? mavcontainer.getModel()。get(name):this.createattribute(name、parameter、bindfactory、webrequest); if(!mavcontainer.isbindingdisabled(name)){modelattribute ann =(modelAttribute)parameter.getParameterAnnotation(ModelAttribute.Class); if(ann!= null &&!ann.binding()){mavcontainer.setbindingDisabled(name); }} webdatabinder binder = bindfactory.createbinder(webrequest、属性、name); if(binder.getTarget()!= null){if(!mavcontainer.isbindingdisabled(name)){this.bindrequestParameters(binder、webrequest); } this.validateifApplible(バインダー、パラメーター); if(binder.getbindingResult()。haserrors()&& this.isbindexceptionrequired(binder、parameter)){show new bindexception(binder.getbindingResult()); }} map <string、object> bindingResultModel = binder.getBindingResult()。getModel(); mavcontainer.removeattributes(BindingResultModel); mavcontainer.addallattributes(BindingResultModel); return binder.convertifn decessary(binder.getTarget()、parameter.getParametertype()、parameter);}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。