当前位置:网站首页>Éléments de base de la validation des haricots - 04
Éléments de base de la validation des haricots - 04
2022-07-23 16:10:00 【Big buggy Love Buggy】
Bean ValidationÉléments de base----04
Introduction
Comprendre le contexte du vérificateurValidatorContext,Sachant qu'il peut vérifierValidatorLes cinq principaux composants du noyau sont personnalisés,Quel rôle ces composants de base jouent - ils dans le processus de vérification?,Dans cet article.
En tant qu'élément central,Il est nécessaire d'en savoir plus..Sur cette base,La diffusion, la compréhension et l'utilisation d'autres modules fonctionnels seront comme de l'eau..Mais le processus est vraiment ennuyeux,C'est pour ça qu'il faut insister..
Bean ValidationLes cinq composants de base du vérificateur passent parValidatorContextPeut être défini séparément:Si ce n'est pas réglé(Ounull), Alors revenez à l'utilisation ValidatorFactory Composant par défaut .
Composants prêts ,Adoption uniformeValidatorFactory Exposé à l'accès :
public interface ValidatorFactory extends AutoCloseable {
...
MessageInterpolator getMessageInterpolator();
TraversableResolver getTraversableResolver();
ConstraintValidatorFactory getConstraintValidatorFactory();
ParameterNameProvider getParameterNameProvider();
@since 2.0
ClockProvider getClockProvider();
...
}
MessageInterpolator
Traduction littérale:Interpolateur de messages. Pas très facile à comprendre littéralement :C'est tout simplement vrai.messageFormatage du contenu,S'il y a un substituant{}OuelExpression${}Effectuer des remplacements et des calculs. Les erreurs grammaticales doivent être tolérées autant que possible .
La vérification d'un modèle de message défaillant lui donne un format de message lisible par l'homme , Il est donc capable de gérer l'internationalisation des messages :MessagekeyC'est le même, Mais selon Locale Afficher différents modèles de message . Enfin en remplacement de / Placeholder dans le modèle technique ~
C'estBean ValidationInterface standard pour,Hibernate ValidatorFournit une mise en œuvre:

Hibernate ValidationIl utiliseResourceBundleMessageInterpolatorPour supporter à la fois les paramètres,- Oui.ELExpression.
javax.el.ExpressionFactoryC'estAPIPour soutenirELExpression${}De,Comme ça.:must be greater than ${inclusive == true ? 'or equal to ' : ''}{value}Il est capable de calculer dynamiquement${inclusive == true ? 'or equal to ' : ''}La valeur de cette partie.
public interface MessageInterpolator {
String interpolate(String messageTemplate, Context context);
String interpolate(String messageTemplate, Context context, Locale locale);
}
Méthode d'interface simple :Selon le contexteContext Remplir le modèle de message messageTemplate. Son flux de travail spécifique est illustré ci - dessous :

context En général, le contexte a besoin d'être remplacé keyLa valeur de la clé est correcte,Comme le montre la figure ci - dessous:

HibernateC'est exact.Context L'implémentation de a étendu deux Map(NonJSRCritères), Peut vous donner la priorité sur constraintDescriptorValeur, Je ne peux plus fallback En mode standard ConstraintDescriptorValeur intérieure, C'est la valeur de propriété de l'annotation . Les codes de valeur spécifiques sont les suivants: :
ParameterTermResolver:
private Object getVariable(Context context, String parameter) {
// Commencez parhibernate Valeur de la méthode étendue
if (context instanceof HibernateMessageInterpolatorContext) {
Object variable = ( (HibernateMessageInterpolatorContext) context ).getMessageParameters().get( parameter );
if ( variable != null ) {
return variable;
}
}
// fallback En mode standard : Valeur de l'attribut annotation
return context.getConstraintDescriptor().getAttributes().get( parameter );
}
Dans la plupart des cas, nous n'obtenons que les valeurs des attributs d'annotation , C'est - à - dire que le message d'erreur peut être utilisé { Annotation nom de l'attribut } Ceci obtient dynamiquement la valeur de l'attribut d'annotation , Donner un message d'erreur amical .
Dans le contexteMessageParamètres etExpression Comment mettre les paramètres ? Dans la section utilisation avancée ultérieure , Sera personnalisé k-vRemplacer les paramètres, Les connaissances avancées en application de cette section seront également utilisées , Voir plus loin .
TraversableResolver
Processeur capable de traverser . Littéralement, c'est très difficile à comprendre. , Dans un langage grossier :Déterminer si une propriété peut êtreValidationProviderAccès à, Chaque fois que vous accédez à un attribut, vous le jugez d'un coup ,Fournir deux méthodes de jugement:
public interface TraversableResolver {
// Si elle est accessible
boolean isReachable(Object traversableObject,
Node traversableProperty,
Class<?> rootBeanType,
Path pathToTraversableObject,
ElementType elementType);
// Est cascade(Indique s'il y [email protected])
boolean isCascadable(Object traversableObject,
Node traversableProperty,
Class<?> rootBeanType,
Path pathToTraversableObject,
ElementType elementType);
}
L'interface est principalement jugée en fonction des éléments de configuration,Pas responsable..Pour usage interne, L'appelant n'a pas besoin de s'en soucier. , Il n'y a pas non plus de mécanisme de modification par défaut ,Pour l'instant.
ConstraintValidatorFactory
Usine de contrôle des contraintes .ConstraintValidator Nous ne devrions pas être étrangers au vérificateur des contraintes : Chaque annotation de contrainte doit spécifier un / Plusieurs validateurs de contraintes ,Comme ça.:
@Constraint(validatedBy = {
xxx.class }).
ConstraintValidatorFactory C'est l'usine :Peut être basé surClassGénérer une instance objet.
public interface ConstraintValidatorFactory {
// Générer une instance:L'interface ne précise pas comment vous générez
<T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key);
// Exemple de libération.Marquer cette instance n'est plus nécessaire,Implémentation généralement vide
// EtSpringLorsque le conteneur est intégré .destroyBean(instance)Cette méthode est appelée lorsque
void releaseInstance(ConstraintValidator<?, ?> instance);
}
HibernateFournit une mise en œuvre uniqueConstraintValidatorFactoryImpl:Générer une instance en utilisant un constructeur vide clazz.getConstructor().newInstance();.
Conseils: L'interface n'indique pas comment générer une instance ,Hibernate Validator C'est ce qui s'est passé avec la construction vide ~
ParameterNameProvider
Fournisseur de noms de paramètres.Ce composant etSpringDeParameterNameDiscoverer C'est pareil. :Méthode d'obtention/ Nom du paramètre du constructeur .
public interface ParameterNameProvider {
List<String> getParameterNames(Constructor<?> constructor);
List<String> getParameterNames(Method method);
}
Mise en œuvre fournie:
- DefaultParameterNameProvider:Basé surJavaRéflexeAPI Executable#getParameters()Réalisation
@Test
public void test9() {
ParameterNameProvider parameterNameProvider = new DefaultParameterNameProvider();
// Prends ça.Person Structure non paramétrique et structure paramétrique (@[email protected])
Arrays.stream(Person.class.getConstructors()).forEach(c -> System.out.println(parameterNameProvider.getParameterNames(c)));
}
Exécuter le programme,Produits:
[arg0, arg1, arg2, arg3]
[]
Même chose, Si vous souhaitez imprimer un nom de paramètre explicite , Veuillez ajouter aux paramètres de compilation -parametersParamètres.
- ReflectionParameterNameProvider:Expiré.Veuillez utiliser ledefaultRemplacer
- ParanamerParameterNameProvider:Basé surcom.thoughtworks.paranamer.Paranamer Implémenter l'acquisition du nom du paramètre , Les paquets correspondants doivent être importés en plus. .
ClockProvider
Fournisseur d'horloges.Cette interface est simple,Est de fournir unClock,Voilà[email protected]、@FutureFournir une référence pour le jugement de lecture.La seule mise en œuvre estDefaultClockProvider:
public class DefaultClockProvider implements ClockProvider {
public static final DefaultClockProvider INSTANCE = new DefaultClockProvider();
private DefaultClockProvider() {
}
// La valeur par défaut est l'horloge système
@Override
public Clock getClock() {
return Clock.systemDefaultZone();
}
}
Par défaut, l'horloge système actuelle est utilisée comme référence . Si votre système a des normes de référence globalement harmonisées , Comme l'horloge unifiée , Cela vous permettra d'implémenter votre propre ClockHorloge, Après tout, le temps de chaque serveur n'est pas garanti d'être exactement le même , C'est un scénario d'application sensible au temps ( Par exemple, appel d'offres )C'est nécessaire.
Ce qui précède est justeValidator Une description des cinq composantes principales du vérificateur , Dans l'ensemble, c'est assez simple. . Dont le premier élément :MessageInterpolator Je pense que l'interpolateur est le plus important , Il faut comprendre . Faire un modèle de message personnalisé plus tard 、 Les messages internationaux sont utiles .
ValueExtractor
Extracteur de valeur.2.0 La version ajoute un composant plus important API,Action:Extraire la valeur du conteneur. Les contenants ici comprennent :Tableau、Ensemble、Map、OptionalAttendez un peu!.
// T:Type de conteneur à extraire
public interface ValueExtractor<T> {
// De la valeur originaleoriginalValueExtrait dereceiver- Oui.
void extractValues(T originalValue, ValueReceiver receiver);
// Fournir un ensemble de méthodes,Pour recevoirValueExtractorLa valeur extraite
interface ValueReceiver {
// Recevoir les valeurs extraites de l'objet
void value(String nodeName, Object object);
// Recevoir des valeurs itératives,Par exemple:List、Map、IterableAttendez.
void iterableValue(String nodeName, Object object);
// Recevoir une valeur indexée,Par exemple:List Array
// i:Valeur de l'index
void indexedValue(String nodeName, int i, Object object);
// Recevoir les valeurs des paires de clés,Par exemple:Map
void keyedValue(String nodeName, Object key, Object object);
}
}
Facile à penser,ValueExtractor Il y a beaucoup de classes d'implémentation ( Toutes les classes de mise en œuvre sont intégrées ,NonpublicDe, C'est le type de conteneur supporté par défaut ):

Exemples de deux implémentations typiques :
// ExtractionListValeur en LIST_ELEMENT_NODE_NAME -> <list element>
class ListValueExtractor implements ValueExtractor<List<@ExtractedValue ?>> {
static final ValueExtractorDescriptor DESCRIPTOR = new ValueExtractorDescriptor( new ListValueExtractor() );
private ListValueExtractor() {
}
@Override
public void extractValues(List<?> originalValue, ValueReceiver receiver) {
for ( int i = 0; i < originalValue.size(); i++ ) {
receiver.indexedValue( NodeImpl.LIST_ELEMENT_NODE_NAME, i, originalValue.get( i ) );
}
}
}
// ExtractionOptionalValeur en
@UnwrapByDefault
class OptionalLongValueExtractor implements ValueExtractor<@ExtractedValue(type = Long.class) OptionalLong> {
static final ValueExtractorDescriptor DESCRIPTOR = new ValueExtractorDescriptor( new OptionalLongValueExtractor() );
@Override
public void extractValues(OptionalLong originalValue, ValueReceiver receiver) {
receiver.value( null, originalValue.isPresent() ? originalValue.getAsLong() : null );
}
}
CalibrateurValidator Il permet d'extraire la valeur du conteneur pour participer à la vérification , À partir de là, vous devriez être capable de comprendre Mao de Bean Validation2.0 Commencez par prendre en charge la validation des éléments dans le conteneur ,Comme ça.:List<@NotNull @Valid Person>、Optional<@NotNull @Valid Person>, C'est très pratique. .
Si vous avez un conteneur personnalisé , Exigences à extraire , Alors vous pouvez personnaliser ValueExtractorRéalisation,Et à traversValidatorContext#addValueExtractor()Il suffit de l'ajouter
RÉFÉRENCES
4. ValidatorLes cinq principaux composants du calibrateur,Il n'y en a pas moins
边栏推荐
- Harbor image warehouse
- It's too hard! Tencent T4 boss was still staying up late at 4 a.m. and was actually sorting out the distributed transaction notes
- redis 主从复制
- harbor镜像仓库
- pydensecrf安装
- 专访|开源之夏新星牛学蔚
- As a tester, you cannot fail to understand ADB commands and operations
- ICML 2022 | 稀疏双下降:网络剪枝也能加剧模型过拟合?
- FMDB的封装与使用
- Mysql—六大日志
猜你喜欢

What is the real HTAP? (2) Challenge article

备份内容哈哈哈

现代商业无代码开发平台的治理和网络安全

Expression du suffixe (une question par jour pendant les vacances d'été 4)

Quickly master QML Chapter 5 components

Idées de conception sur l'initialisation des paramètres d'entrée de page

云服务器ECS远程监控

服务器性能调优经验总结

C language learning notes

W3C 推出去中心化标识符作为 Web 标准
随机推荐
Bubble sort - just read one
封面 - 电脑知识指南
浅谈‘过早优化’
ORA-01654错误:表空间满了,插入失败
24 道几乎必问的 JVM 面试题,我只会 7 道,你能答出几道?
Mysql—六大日志
Axure advanced
Mathematical Modeling Typesetting
SharedPreferences data storage
[attack and defense world web] difficulty Samsung 9 points introductory question (Part 2): shrink, lottery
[attack and defense world web] difficulty Samsung 9 points introductory question (Part 1): simple_ js、mfw
来自大佬洗礼!2022头条首发纯手打MySQL高级进阶笔记,吃透P7有望
手机使用多了可能会丢掉工作
Mysql—主从复制
Learning about patents
《快速掌握QML》第四章 事件处理
Google Earth Engine——影像统计过程中出现的空值问题
LeetCode高频题:最少经过几次操作可以使数组变为非降序状态
New infrastructure of enterprise data in the era of digital transformation | love Analysis Report
备份内容哈哈哈