Cet article présente brièvement comment introduire des étapes de validation, comment réduire la quantité de code par la validation personnalisée et améliorer la productivité. Mention spéciale: valide des attributs de type non primitif, traitement des méthodes GET, résolution unifiée des messages d'erreur de validation.
La mise en œuvre réelle de la validation dans cet article est confiée à la validation d'hibernate pour le traitement
Configuration de base
Pom présente les dépendances Maven
<! - Validation Begin -> <dependency> <proupId> javax.validation </rom grouped> <ArtifActid> Validation-API </ Artifactid> <DERVERSE> 1.1.0.Final </DERNIFRIENT> </DENFACTID> <Dendency> <ProupId> org.hibernate </proupId> <Artifactid> Hibernate-Validator </ ArtifactId> <version> 5.4.0.Final </ Version> </ Dependency> <! - Validation End ->
Ajouter la configuration de validation
Ajoutez la configuration suivante à Spring-MVC-Servlet.xml:
<mvc: annotation-diriging validator = "validator"> <bean id = "validator"> <propriété name = "providerClass" value = "org.hibernate.validator.hibernatevalidator" /> <propriété name = "validationMessagesource" ref = "messageSource"
Excepteur personnalisé
Personnalisez le message d'erreur de validation et les informations renvoyées à l'appelant sont plus amicales. La configuration suivante est ajoutée à l'applicationContext.xml:
<! - Chargez le fichier de ressources de message i18n -> <bean id = "MessageSource"> <propriété name = "Basenames"> <s liste> <value> errormsg </value> <value> validation_error </value> </sist> </proprime> </anEn> <bean id = "ValidationExceptionResResolver" />
Ajouté au projet ClassPath: validation_error_zh_cn.properties Fichier de ressources:
#La erreur msg pour la validation d'entrée # Commonfield.can.not.be.null = {champ} ne peut pas être un champ vide.can.not.be.empty = {champ} ne peut pas être vide ou vide Field.must.be.greater.than.Min = {Field} ne peut pas être inférieur à {valeur} ne peut pas être plus que} Implémentation de ValidationExceptionResovler:
ValidationExceptionResovler.java
@ SLF4JPublic Class ValidationExceptionResoVler étend AbstrathandleRexceptionResolver {public validationExceptionResovler () {// Définissez l'ordre et exécutez ce.SetOrder (0); } / ** * Gérer le cas où un argument annoté avec {@code @valid} tel que * un {@link} ou {@link} échoue la validation. * <p> * Gestionnaire d'exception de validation de validation personnalisée * Obtenez le message d'erreur de validation spécifique et assemblez CommonPonse et retournez à l'appelant. * * @param demande de demande HTTP actuelle * @param réponse actuelle réponse http * @param manageur le gestionnaire exécuté * @return un modélisation vide, indiquant que l'exception a été gérée * @Throws ioexception potentiellement jetée à partir de réponse.Senderror () * / @ResponseBody Protected ModelAwView Request, HttpServletResponse Response, Object Handler) lève ioException {list <objectorror> errors = bindingResult.getAllErrors (); StringBuffer errmsgbf = new StringBuffer (); pour (objectorror error: errers) {String mass = error.getDefaultMessage (); errmsgbf.append (massage); errmsgbf.append ("||"); } String errmsgString = errmsgbf.toString (); errmsgString = errmsgString.length ()> 2? errmsgString.SubString (0, errmsgString.Length () - 2): errmsgString; log.Error ("Validation a échoué! {}", errmsgString); Map <string, objet> map = new Treemap <String, objet> (); map.put ("succès", false); map.put ("errorcode", "9999"); map.put ("errormsg", errmsgString); ModelAndView mav = new ModelAndView (); Mappingjackson2jsonView View = new MappingJackSon2JSonView (); View.SetAttributesMap (MAP); mav.setView (vue); retourner mav; } @Override Protected ModelAndView DoresolException (HttpServLetRequest Request, HttpServletResponse Response, Handler d'objet, exception ex) {BindingResult BindingResult = null; if (ex instanceOf MethodargumentNotValidexception) {binkingResult = ((methodargumentNotValidexception) ex) .getBindingResult (); } else if (ex instanceof bindException) {bindingResult = ((bindException) ex) .getBindingResult (); } else {// autre exception, ignore} if (binkingResult! = null) {try {return handleMethodargumentNotValidexception (bindingResult, request, réponse, gestionnaire); } catch (ioException e) {log.Error ("DoresolException:", e); }} return null; }} Ajouter @valid dans Controller
@RequestMapping ("/ acheter") @ ResponseBodyPublic BaseSheResponse Buy (@Requestbody @valid BuyflowerRequest Request) Jette l'exception {// ......} Ajouter une annotation de validation aux attributs qui nécessitent une validation sur le haricot de demande
@ Seter @ getterpublic class BuyflowerRequest {@Notempty (message = "{name.can.not.be.null}") Nom de chaîne privée;} Validation des objets secondaires
La méthode d'écriture ci-dessus ne peut vérifier que les attributs de type de base de BuyflowerRequest, mais il n'y a aucun moyen de valider les attributs des attributs d'objet. Si vous devez valider les attributs de l'objet secondaire, vous devez ajouter @valid et des annotations de validation spécifiques à l'objet secondaire et aux attributs d'objet secondaire en même temps.
La méthode d'écriture suivante:
@ Seter @ getterpublic classe BuyflowerRequest {@Notempty (field = "bianName") Nom de chaîne privée; @Min (field = "prix", valeur = 1) Private Int Prix; @Notnull Liste privée <AnTYPE> PayTypeList;} @ seter @ getterpublic class PayType {@valid @min (value = 1) private int PayType; @Valid @min (valeur = 1) private int payamount;} Réduire davantage le nombre d'encodages
Afin de réduire la charge de travail de codage, via des annotations de validation personnalisées, essayez de passer le nom de validation déposé au fichier de ressource du message d'erreur, évitant ainsi d'écrire différents modèles de messages pour chaque domaine.
Voici un exemple du @notnull réécrit:
1. Définir l'annotation de validation, noter que le champ () est ajouté par rapport à l'annotation native, qui est utilisée pour passer le nom déposé qui est validé.
Notnull.java
@Target ({elementType.Method, elementType.field, elementType.annotation_type, elementType.Constructor, elementType.Parameter}) @ CONSTRAINTION (VALIDEDBY = {NotnullValidator.class}) @ rétention (rétentionpolicy.runtime) public @interface notnull {string field ("" ""; String message () par défaut "{champ.can.not.be.null}"; Classe <?> [] Groupes () default {}; Classe <? étend la charge utile> [] la charge utile () par défaut {};} 2. Définir Validator, tous les validateurs implémentent l'interface CONSTRAINTVALIDATEUR:
Notnullvalidator.java
classe publique notnullValidator implémente CONSTRAINTVALIDATOR <NOTNULL, Object> {@Override public void initialize (notnull Annotation) {} @Override public boolean isvalid (objet str, contraintValidatorContext ConstraintValidatorContext) {return str! = null; }} 3. Ajouter une annotation de validation au dépôt, faites attention à la spécification de la valeur déposée. Si le message n'a pas d'exigence personnalisée, vous n'avez pas besoin de le spécifier. Le composant de validation remplira le message par défaut par lui-même.
AcheterflowerRequest.java
@ Seter @ getterpublic classe BuyflowerRequest {@Notempty (field = "bianName") Nom de chaîne privée; @Min (field = "prix", valeur = 1) Private Int Price;} Remarque: L'annotation @notnull prend déjà en charge la vérification spéciale de la liste. Pour les nœuds de type liste, si list == null || list.size () == 0 renvoie false et la validation échoue. Actuellement, les annotations @NotNull, @Notempty, @min, @max ont été personnalisées selon cette idée et peuvent être trouvées dans le projet de marchandises.
Prise en charge des demandes de GET
Les exemples ci-dessus sont toutes les demandes de poste. @Requestbody peut résoudre les demandes de poste, mais ils ne prennent pas en charge les demandes de GET. Lisez la documentation et le code source de Spring et a constaté que @ModelAtTribute peut résoudre les demandes d'obtention dans les haricots et la validation du support. Pour plus de détails, vous pouvez lire le code source Spring: ModelAtTrributeMethodProcessor.ResolVeargument ().
Exemple d'utilisation:
@RequestMapping (value = "/ buy", méthode = requestMethod.get) @ResponseBodyPublic BaseResponse Detail (@Valid @ModeLatTribute DetailFlowerRequest Request) lève une exception {DetailFlowerSponse Response = new DetailflowerResponse (); réponse.setName (request.getName ()); return resultFactory.success (réponse, BaseSesponse.class);} FAIRE
1. Développez la validation en fonction des scénarios commerciaux, tels que: format de date, montant, etc.
2. Validation de support de la vérification des relations multiples sur le terrain
Pièce jointe: Code de clé d'implémentation de validation de printemps
@Requestbody
Classe d'implémentation: demandesResponseBodyMethodProcessor.java
Public Object ResolVeargument (paramètre MethodParameter, ModelandViewContainer MavContainer, nativeweBrequest webRequest, webDatabinderFactory BinderFactory) lève une exception {objet arg = this.readwithMessageConverters (webrequest, paramètre, paramètre.getGenericPaMeterType ()); String name = Conventions.getVariabbleNameForParAmètre (paramètre); WebDataBinder Binder = bindFactory.CreateBinder (WebRequest, arg, nom); if (arg! = null) {this.validateIfApplicable (linder, paramètre); if (binder.getBindingResult (). Haserrors () && this.isbindexceptionRequired (Binder, Paramètre)) {Throw new MethodArgumentNotValidexception (Paramètre, Binder.GetBindingResult ()); }} mavContainer.addattribute (bindingResult.model_key_prefix + name, binder.getBindingResult ()); retourner arg;} @Modelattuite
Classe d'implémentation: ModelAtTributEMethodProcessor.java
Public Final Object ResolVeargument (Paramètre MethodParAmètre, ModelAndViewContainer MavContainer, nativewebRequest webRequest, webDatabinderFactory BinderFactory) lève exception {String name = modelfactory.getNameForParAmètre (paramètre); Objet attribut = mavContainer.ContaintAttribute (name)? mavContainer.getModel (). get (name): this.CreatEatTribute (nom, paramètre, 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, attribut, name); if (binder.getTtarget ()! = null) {if (! mavContainer.isbindingDisabled (name)) {this.bindRequestParameters (Binder, webRequest); } this.validateIFAPLICABLE (liant, paramètre); if (binder.getBindingResult (). Haserrors () && this.isbindexceptionRequired (Binder, Paramètre)) {Throw New BindException (Binder.GetBindingResult ()); }} Map <string, objet> bindingResultModel = Binder.getBindingResult (). GetModel (); MavContainer.RemoveAtTributes (BindingResultModel); MavContainer.AddallAttributes (BindingResultModel); return Binder.Convertifnessary (Binder.getTarget (), paramètre.getParameterType (), paramètre);}Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.