Comment SpringBoot effectue-t-il la vérification des paramètres ?
Introduction
Dans le développement quotidien d'interfaces, afin d'éviter que des paramètres illégaux n'affectent l'entreprise, il est souvent nécessaire de vérifier les paramètres de l'interface. Par exemple, il est nécessaire de vérifier si le nom d'utilisateur et le mot de passe sont vides lors de la connexion. dans et lors de l'ajout d'un utilisateur, les formats de l'adresse e-mail et du numéro de téléphone portable de l'utilisateur sont-ils corrects ? Il serait trop fastidieux de s'appuyer sur du code pour vérifier les paramètres de l'interface un par un, et la lisibilité du code serait extrêmement mauvaise.
Validator
Le framework est conçu pour aider les développeurs à écrire moins de code pendant le développement et à améliorer l'efficacité du développement ; Validator est spécialement utilisé pour vérifier les paramètres d'interface, tels que la vérification requise commune, la vérification du format de courrier électronique, le nom d'utilisateur doit être compris entre 6 et Attendre entre 12. et ainsi de suite.
Voyons ensuite comment intégrer le framework de vérification des paramètres dans SpringbBoot.
1. Vérification des paramètres intégrée dans SpringBoot
1.1 Introduire les dépendances
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
1.2 Définir les classes d'entités de paramètres
package com.didiplus.modules.sys.domain; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 字典类型领域模型 */ @Data @ApiModel(value = "字典类型") public class SysDictType { @ApiModelProperty("ID") private String id; @NotBlank(message = "字典名称必填项") @ApiModelProperty(value = "字典名称",example = "用户ID") private String typeName; @NotBlank(message = "字典编码不能为空") @ApiModelProperty(value = "字典编码") private String typeCode; @Email(message = "请填写正确的邮箱地址") @ApiModelProperty(value = "字典编码") private String email; @ApiModelProperty(value = "字典描述") private String description; @NotBlank(message = "字典状态不能为空") @ApiModelProperty(value = "字典状态") private String enable; }
Les annotations de contraintes courantes sont les suivantes :
Annotations | Fonction |
---|---|
@AssertFal se | D'accord, cela peut être nul. Si ce n'est pas nul, cela doit être faux |
@Digits | |
@Future | |
@Past | |
@Max | |
@Min | |
@NotNull | |
@Null | |
@Pattern | |
@Size | |
@Length | |
@NotBlank | |
@NotEmpty | |
; | @Plage |
@URL | |
1.3定义校验类进行测试package com.didiplus.modules.sys.controller; import com.didiplus.modules.sys.domain.SysDictType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.parameters.RequestBody; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 数据字典控制器 */ @RestController @Api(tags = "数据字典") @RequestMapping("/api/sys/dictType") public class SysDictTypeController { @ApiOperation("字典添加") @PostMapping("/add") public SysDictType add(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } @ApiOperation("字典修改") @PutMapping("/edit") public SysDictType edit(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } } Copier après la connexion 这里我们先定义两个方法 1.4打开接口文档模拟提交数据通过接口文档看到前三个字段都是必填项。 由于email的格式不对就被拦截了,提示是因为邮箱地址不对。 2.参数异常加入全局异常处理器虽然我们之前定义了全局异常拦截器,也看到了拦截器确实生效了,但是 直接修改之前定义的
代码如下: package com.didiplus.common.web.response.Handler; import com.didiplus.common.web.response.Result; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.stream.Collectors; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/24 * Desc: 默认全局异常处理。 */ @RestControllerAdvice public class RestExceptionHandler { /** * 默认全局异常处理。 * @param e the e * @return ResultData */ @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class}) public ResponseEntity<Result<String>> handleValidatedException(Exception e) { Result<String> result = null; if (e instanceof MethodArgumentNotValidException) { MethodArgumentNotValidException ex =(MethodArgumentNotValidException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getBindingResult().getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } else if (e instanceof ConstraintViolationException){ ConstraintViolationException ex = (ConstraintViolationException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getConstraintViolations().stream() .map(ConstraintViolation::getMessage) .collect(Collectors.joining(";")) ); }else if (e instanceof BindException) { BindException ex = (BindException ) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } return new ResponseEntity<>(result,HttpStatus.BAD_REQUEST); } } Copier après la connexion 美化之后错误信息提示更加友好 3.自定义参数校验虽然Spring Validation 提供的注解基本上够用,但是面对复杂的定义,我们还是需要自己定义相关注解来实现自动校验。 3.1创建自定义注解package com.didiplus.common.annotation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Repeatable(EnumString.List.class) @Documented @Constraint(validatedBy = EnumStringValidator.class)//标明由哪个类执行校验逻辑 public @interface EnumString { String message() default "value not in enum values."; Class<?>[] groups() default {}; Class<? extends Payload>[] palyload() default {}; /** * @return date must in this value array */ String[] value(); /** * Defines several {@link EnumString} annotations on the same element. * * @see EnumString */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Documented @interface List { EnumString[] value(); } } Copier après la connexion 3.2自定义校验逻辑package com.didiplus.common.annotation; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.List; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public class EnumStringValidator implements ConstraintValidator<EnumString,String> { private List<String> enumStringList; @Override public void initialize(EnumString constraintAnnotation) { enumStringList = Arrays.asList(constraintAnnotation.value()); } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { if(value == null) { return true; } return enumStringList.contains(value); } } Copier après la connexion 3.3在字段上增加注解@ApiModelProperty(value = "性别") @EnumString(value = {"F","M"}, message="性别只允许为F或M") private String sex; Copier après la connexion 3.4体验效果4.分组校验一个对象在新增的时候某些字段是必填,在更新是有非必填。如上面的 其实 4.1定义分组接口package com.didiplus.common.base; import javax.validation.groups.Default; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public interface ValidGroup extends Default { interface Crud extends ValidGroup{ interface Create extends Crud{ } interface Update extends Crud{ } interface Query extends Crud{ } interface Delete extends Crud{ } } } Copier après la connexion 4.2在模型中给参数分配分组@Null(groups = ValidGroup.Crud.Create.class) @NotNull(groups = ValidGroup.Crud.Update.class,message = "字典ID不能为空") @ApiModelProperty("ID") private String id; Copier après la connexion 4.3体现效果Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois! Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
![]() Outils d'IA chauds![]() Undresser.AI UndressApplication basée sur l'IA pour créer des photos de nu réalistes ![]() AI Clothes RemoverOutil d'IA en ligne pour supprimer les vêtements des photos. ![]() Undress AI ToolImages de déshabillage gratuites ![]() Clothoff.ioDissolvant de vêtements AI ![]() Video Face SwapÉchangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit ! ![]() Article chaud
Assassin's Creed Shadows: Solution d'énigmes de coquille
4 Il y a quelques semaines
By DDD
Quoi de neuf dans Windows 11 KB5054979 et comment résoudre les problèmes de mise à jour
3 Il y a quelques semaines
By DDD
Où trouver la courte de la grue à atomide atomique
4 Il y a quelques semaines
By DDD
<🎜>: Dead Rails - Comment relever chaque défi
1 Il y a quelques mois
By DDD
Guide de l'atomfall: emplacements des articles, guides de quête et conseils
1 Il y a quelques mois
By DDD
![]() Outils chauds![]() Bloc-notes++7.3.1Éditeur de code facile à utiliser et gratuit ![]() SublimeText3 version chinoiseVersion chinoise, très simple à utiliser ![]() Envoyer Studio 13.0.1Puissant environnement de développement intégré PHP ![]() Dreamweaver CS6Outils de développement Web visuel ![]() SublimeText3 version MacLogiciel d'édition de code au niveau de Dieu (SublimeText3) ![]() Sujets chauds![]() Introduction à Jasypt Jasypt est une bibliothèque Java qui permet à un développeur d'ajouter des fonctionnalités de chiffrement de base à son projet avec un minimum d'effort et ne nécessite pas une compréhension approfondie du fonctionnement du chiffrement. Haute sécurité pour le chiffrement unidirectionnel et bidirectionnel. technologie de cryptage basée sur des normes. Cryptez les mots de passe, le texte, les chiffres, les binaires... Convient pour l'intégration dans des applications basées sur Spring, API ouverte, pour une utilisation avec n'importe quel fournisseur JCE... Ajoutez la dépendance suivante : com.github.ulisesbocchiojasypt-spring-boot-starter2 1.1. Les avantages de Jasypt protègent la sécurité de notre système. Même en cas de fuite du code, la source de données peut être garantie. ![]() Scénario d'utilisation 1. La commande a été passée avec succès mais le paiement n'a pas été effectué dans les 30 minutes. Le paiement a expiré et la commande a été automatiquement annulée 2. La commande a été signée et aucune évaluation n'a été effectuée pendant 7 jours après la signature. Si la commande expire et n'est pas évaluée, le système donne par défaut une note positive. 3. La commande est passée avec succès. Si le commerçant ne reçoit pas la commande pendant 5 minutes, la commande est annulée. 4. Le délai de livraison expire et. un rappel par SMS est envoyé... Pour les scénarios avec des délais longs et de faibles performances en temps réel, nous pouvons utiliser la planification des tâches pour effectuer un traitement d'interrogation régulier. Par exemple : xxl-job Aujourd'hui, nous allons choisir ![]() 1. Redis implémente le principe du verrouillage distribué et pourquoi les verrous distribués sont nécessaires. Avant de parler de verrous distribués, il est nécessaire d'expliquer pourquoi les verrous distribués sont nécessaires. Le contraire des verrous distribués est le verrouillage autonome. Lorsque nous écrivons des programmes multithreads, nous évitons les problèmes de données causés par l'utilisation d'une variable partagée en même temps. Nous utilisons généralement un verrou pour exclure mutuellement les variables partagées afin de garantir l'exactitude de celles-ci. les variables partagées. Son champ d’utilisation est dans le même processus. S’il existe plusieurs processus qui doivent exploiter une ressource partagée en même temps, comment peuvent-ils s’exclure mutuellement ? Les applications métier d'aujourd'hui sont généralement une architecture de microservices, ce qui signifie également qu'une application déploiera plusieurs processus si plusieurs processus doivent modifier la même ligne d'enregistrements dans MySQL, afin d'éviter les données sales causées par des opérations dans le désordre, les besoins de distribution. à introduire à ce moment-là. Le style est verrouillé. Vous voulez marquer des points ![]() Springboot lit le fichier, mais ne peut pas accéder au dernier développement après l'avoir empaqueté dans un package jar. Il existe une situation dans laquelle Springboot ne peut pas lire le fichier après l'avoir empaqueté dans un package jar. La raison en est qu'après l'empaquetage, le chemin virtuel du fichier. n’est pas valide et n’est accessible que via le flux Read. Le fichier se trouve sous les ressources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input ![]() Lorsque Springboot+Mybatis-plus n'utilise pas d'instructions SQL pour effectuer des opérations d'ajout de plusieurs tables, les problèmes que j'ai rencontrés sont décomposés en simulant la réflexion dans l'environnement de test : Créez un objet BrandDTO avec des paramètres pour simuler le passage des paramètres en arrière-plan. qu'il est extrêmement difficile d'effectuer des opérations multi-tables dans Mybatis-plus. Si vous n'utilisez pas d'outils tels que Mybatis-plus-join, vous pouvez uniquement configurer le fichier Mapper.xml correspondant et configurer le ResultMap malodorant et long, puis. écrivez l'instruction SQL correspondante Bien que cette méthode semble lourde, elle est très flexible et nous permet de ![]() SpringBoot et SpringMVC sont tous deux des frameworks couramment utilisés dans le développement Java, mais il existe des différences évidentes entre eux. Cet article explorera les fonctionnalités et les utilisations de ces deux frameworks et comparera leurs différences. Tout d’abord, découvrons SpringBoot. SpringBoot a été développé par l'équipe Pivotal pour simplifier la création et le déploiement d'applications basées sur le framework Spring. Il fournit un moyen rapide et léger de créer des fichiers exécutables autonomes. ![]() 1. Personnalisez RedisTemplate1.1, mécanisme de sérialisation par défaut RedisAPI. L'implémentation du cache Redis basée sur l'API utilise le modèle RedisTemplate pour les opérations de mise en cache des données. Ici, ouvrez la classe RedisTemplate et affichez les informations sur le code source de la classe. Déclarer la clé, diverses méthodes de sérialisation de la valeur, la valeur initiale est vide @NullableprivateRedisSe ![]() Cet article écrira un exemple détaillé pour parler du développement réel de dubbo+nacos+Spring Boot. Cet article ne couvrira pas trop de connaissances théoriques, mais écrira l'exemple le plus simple pour illustrer comment dubbo peut être intégré à nacos pour créer rapidement un environnement de développement. ![]() |