Table des matières
使用传统方式的弊端
引入依赖
注解说明
一、对实体类进行校验
1、entity
3、controller
3、编写全局统一异常处理
二、针对单个参数进行校验
三、分组校验
四、自定义分组校验
2、CustomSequenceProvider
五、自定义校验
1、定义校验注解
2、实现注解
六、嵌套校验
七、快速失败
注意事项
Maison Java javaDidacticiel Comment vérifier les paramètres SpringBoot

Comment vérifier les paramètres SpringBoot

May 14, 2023 pm 10:04 PM
springboot

    使用传统方式的弊端

    public String addUser(User user) {
         if (user == null || user.getId() == null || user.getAccount() == null || user.getPassword() == null || user.getEmail() == null) {
             return "对象或者对象字段不能为空";
         }
         if (StringUtils.isEmpty(user.getAccount()) || StringUtils.isEmpty(user.getPassword()) || StringUtils.isEmpty(user.getEmail())) {
             return "不能输入空字符串";
         }
         if (user.getAccount().length() < 6 || user.getAccount().length() > 11) {
             return "账号长度必须是6-11个字符";
         }
         if (user.getPassword().length() < 6 || user.getPassword().length() > 16) {
             return "密码长度必须是6-16个字符";
         }
         if (!Pattern.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", user.getEmail())) {
             return "邮箱格式不正确";
         }
         // 参数校验完毕后这里就写上业务逻辑
         return "success";
     }
    Copier après la connexion

    这样做确实没有什么问题,而且排版也工整,但代码太繁琐了,如果有几十个字段要校验,那这个方法里面将会变得非常臃肿,实在不够优雅。下面我们就来讲讲如何使用最优雅的方式来解决。

    引入依赖

    <dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    Copier après la connexion

    注解说明

    注解说明
    @AssertFalse被注解的元素必须为 false
    @AssertTrue被注解的元素必须为 true
    @DecimalMax(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
    @DecimalMin(value)被注解的元素必须是一个数字,其值必须大于等于指定的最小值
    @Digits (integer, fraction)被注解的元素必须是一个数字,其值必须在可接受的范围内
    @Null被注解的元素必须为空
    @NotNull被注解的元素必须不为空
    @Min(value)被注解的元素必须是一个数字,其值必须大于等于指定的最大值
    @Max(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
    @Size(max, min)被注解的元素的长度必须在指定的范围内
    @Past被注解的元素必须是一个过去的日期
    @Future被注解的元素必须是一个未来的日期
    @Pattern(value)被注解的元素必须符合指定的正则表达式

    下面我们以此来在业务中实现

    一、对实体类进行校验

    1、entity

    @Data
    public class User {
        @NotNull(message = "用户id不能为空")
        private Long id;
        @NotNull(message = "用户账号不能为空")
        @Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
        private String account;
        @NotNull(message = "用户密码不能为空")
        @Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")
        private String password;
        @NotNull(message = "用户邮箱不能为空")
        @Email(message = "邮箱格式不正确")
        private String email;
    }
    Copier après la connexion

    2、controller

    @RestController
    public class UserController {
        @PostMapping("/addUser")
        public void addUser(@RequestBody @Valid User user) {
    		//业务
        }
    }
    Copier après la connexion

    3、编写全局统一异常处理

    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 java.util.stream.Collectors;
    /**
     * 全局异常处理
     *
     * @author master
     */
    @RestControllerAdvice
    public class ExceptionConfig {
        /**
         * 参数为实体类
         * @param e
         * @return
         */
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public String handleValidException(MethodArgumentNotValidException e) {
            // 从异常对象中拿到ObjectError对象
            ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
            // 然后提取错误提示信息进行返回
            return objectError.getDefaultMessage();
        }
        /**
         * 参数为单个参数或多个参数
         * @param e
         * @return
         */
        @ExceptionHandler(value = ConstraintViolationException.class)
        public String handleConstraintViolationException(ConstraintViolationException e) {
            // 从异常对象中拿到ObjectError对象
            return e.getConstraintViolations()
                    .stream()
                    .map(ConstraintViolation::getMessage)
                	.collect(Collectors.toList()).get(0);
        }
    }
    Copier après la connexion

    然后我们使用apipost测试

    Comment vérifier les paramètres SpringBoot

    二、针对单个参数进行校验

    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;
    import javax.validation.constraints.NotNull;
    @RestController
    @Validated
    public class TestController {
        @GetMapping("/test")
        public void test(@NotNull(message = "id不能为空") Integer id) {
        }
    }
    Copier après la connexion

    然后我们使用apipost测试

    Comment vérifier les paramètres SpringBoot

    三、分组校验

    场景:在新增时我们需要id为空,但修改时我们又需要id不为空,总不可能搞两个类吧,这时候分组校验的用处就来了

    1、entity

    import lombok.Data;
    import javax.validation.constraints.Email;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    @Data
    public class User {
        public interface Insert{
        }
        public interface Update{
        }
        @NotNull(message = "用户id不能为空",groups = Update.class)
        @Null(message = "用户id必须为空",groups = Integer.class)
        private Long id;
        private String account;
        private String password;
        private String email;
    }
    Copier après la connexion

    2、controller

    @PostMapping("/add")
    public void add(@RequestBody @Validated(User.Insert.class) User user) {
    }
    Copier après la connexion

    添加时就用User.Insert.class,修改时就用User.Update.class

    四、自定义分组校验

    场景:当type为1时,需要参数a不为空,当type为2时,需要参数b不为空。

    1、entity

    import com.example.demo.provider.CustomSequenceProvider;
    import lombok.Data;
    import org.hibernate.validator.group.GroupSequenceProvider;
    import javax.validation.constraints.NotEmpty;
    import javax.validation.constraints.Pattern;
    @Data
    @GroupSequenceProvider(value = CustomSequenceProvider.class)
    public class CustomGroup {
        /**
         * 类型
         */
        @Pattern(regexp = "[A|B]" , message = "类型不必须为 A|B")
        private String type;
        /**
         * 参数A
         */
        @NotEmpty(message = "参数A不能为空" , groups = {WhenTypeIsA.class})
        private String paramA;
        /**
         * 参数B
         */
        @NotEmpty(message = "参数B不能为空", groups = {WhenTypeIsB.class})
        private String paramB;
        /**
         * 分组A
         */
        public interface WhenTypeIsA {
        }
        /**
         * 分组B
         */
        public interface WhenTypeIsB {
        }
    }
    Copier après la connexion

    2、CustomSequenceProvider

    import com.example.demo.controller.CustomGroup;
    import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
    import java.util.ArrayList;
    import java.util.List;
    public class CustomSequenceProvider implements DefaultGroupSequenceProvider<CustomGroup> {
        @Override
        public List<Class<?>> getValidationGroups(CustomGroup form) {
            List<Class<?>> defaultGroupSequence = new ArrayList<>();
            defaultGroupSequence.add(CustomGroup.class);
            if (form != null && "A".equals(form.getType())) {
                defaultGroupSequence.add(CustomGroup.WhenTypeIsA.class);
            }
            if (form != null && "B".equals(form.getType())) {
                defaultGroupSequence.add(CustomGroup.WhenTypeIsB.class);
            }
            return defaultGroupSequence;
        }
    }
    Copier après la connexion

    3、controller

    @PostMapping("/add")
    public void add(@RequestBody @Validated CustomGroup user) {
    }
    Copier après la connexion

    五、自定义校验

    虽然官方提供的校验注解已经满足很多情况了,但还是无法满足我们业务的所有需求,比如校验手机号码,下面我就以校验手机号码来做一个示例。

    1、定义校验注解

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = PhoneValidator.class)
    public @interface Phone {
        String message() default "手机号码格式有误";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    Copier après la connexion

    注:groups和payload是必须要写的,Constraint是使用哪个类来进行校验。

    2、实现注解

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    import java.util.regex.Pattern;
    /**
     * @author master
     */
    public class PhoneValidator implements ConstraintValidator<Phone, Object> {
        @Override
        public boolean isValid(Object telephone, ConstraintValidatorContext constraintValidatorContext) {
            String pattern = "^1[3|4|5|6|7|8|9]\\d{9}$";
            return Pattern.matches(pattern, telephone.toString());
        }
    }
    Copier après la connexion

    最后直接用到参数前面或者实体类变量上面即可。

    六、嵌套校验

    当某个对象中还包含了对象需要进行校验,这个时候我们需要用嵌套校验。

    @Data
    public class TestAA {
        @NotEmpty(message = "id不能为空")
        private String id;
        @NotNull
        @Valid
        private Job job;
        @Data
        public class Job {
            @NotEmpty(message = "content不能为空")
            private String content;
        }
    }
    Copier après la connexion

    七、快速失败

    Spring Validation默认会校验完所有字段,然后才抛出异常。可以通过配置,开启Fali Fast模式,一旦校验失败就立即返回。

    import org.hibernate.validator.HibernateValidator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import javax.validation.Validation;
    import javax.validation.Validator;
    import javax.validation.ValidatorFactory;
    @Configuration
    public class FailFastConfig {
        @Bean
        public Validator validator() {
            ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                    .configure()
                    // 快速失败模式
                    .failFast(true)
                    .buildValidatorFactory();
            return validatorFactory.getValidator();
        }
    }
    Copier après la connexion

    注意事项

    SpringBoot 2.3.x 移除了validation依赖需要手动引入依赖。

    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 Undress

    Undresser.AI Undress

    Application basée sur l'IA pour créer des photos de nu réalistes

    AI Clothes Remover

    AI Clothes Remover

    Outil d'IA en ligne pour supprimer les vêtements des photos.

    Undress AI Tool

    Undress AI Tool

    Images de déshabillage gratuites

    Clothoff.io

    Clothoff.io

    Dissolvant de vêtements AI

    AI Hentai Generator

    AI Hentai Generator

    Générez AI Hentai gratuitement.

    Article chaud

    R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Meilleurs paramètres graphiques
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Comment réparer l'audio si vous n'entendez personne
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25: Comment déverrouiller tout dans Myrise
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

    Outils chauds

    Bloc-notes++7.3.1

    Bloc-notes++7.3.1

    Éditeur de code facile à utiliser et gratuit

    SublimeText3 version chinoise

    SublimeText3 version chinoise

    Version chinoise, très simple à utiliser

    Envoyer Studio 13.0.1

    Envoyer Studio 13.0.1

    Puissant environnement de développement intégré PHP

    Dreamweaver CS6

    Dreamweaver CS6

    Outils de développement Web visuel

    SublimeText3 version Mac

    SublimeText3 version Mac

    Logiciel d'édition de code au niveau de Dieu (SublimeText3)

    Comment Springboot intègre Jasypt pour implémenter le chiffrement des fichiers de configuration Comment Springboot intègre Jasypt pour implémenter le chiffrement des fichiers de configuration Jun 01, 2023 am 08:55 AM

    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.

    Comment SpringBoot intègre Redisson pour implémenter la file d'attente différée Comment SpringBoot intègre Redisson pour implémenter la file d'attente différée May 30, 2023 pm 02:40 PM

    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

    Comment utiliser Redis pour implémenter des verrous distribués dans SpringBoot Comment utiliser Redis pour implémenter des verrous distribués dans SpringBoot Jun 03, 2023 am 08:16 AM

    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

    Comment résoudre le problème selon lequel Springboot ne peut pas accéder au fichier après l'avoir lu dans un package jar Comment résoudre le problème selon lequel Springboot ne peut pas accéder au fichier après l'avoir lu dans un package jar Jun 03, 2023 pm 04:38 PM

    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

    Comparaison et analyse des différences entre SpringBoot et SpringMVC Comparaison et analyse des différences entre SpringBoot et SpringMVC Dec 29, 2023 am 11:02 AM

    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.

    Comment implémenter Springboot+Mybatis-plus sans utiliser d'instructions SQL pour ajouter plusieurs tables Comment implémenter Springboot+Mybatis-plus sans utiliser d'instructions SQL pour ajouter plusieurs tables Jun 02, 2023 am 11:07 AM

    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

    Comment SpringBoot personnalise Redis pour implémenter la sérialisation du cache Comment SpringBoot personnalise Redis pour implémenter la sérialisation du cache Jun 03, 2023 am 11:32 AM

    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

    Comment obtenir la valeur dans application.yml au Springboot Comment obtenir la valeur dans application.yml au Springboot Jun 03, 2023 pm 06:43 PM

    Dans les projets, certaines informations de configuration sont souvent nécessaires. Ces informations peuvent avoir des configurations différentes dans l'environnement de test et dans l'environnement de production, et peuvent devoir être modifiées ultérieurement en fonction des conditions commerciales réelles. Nous ne pouvons pas coder en dur ces configurations dans le code. Il est préférable de les écrire dans le fichier de configuration. Par exemple, vous pouvez écrire ces informations dans le fichier application.yml. Alors, comment obtenir ou utiliser cette adresse dans le code ? Il existe 2 méthodes. Méthode 1 : Nous pouvons obtenir la valeur correspondant à la clé dans le fichier de configuration (application.yml) via le ${key} annoté avec @Value. Cette méthode convient aux situations où il y a relativement peu de microservices. Méthode 2 : En réalité. projets, Quand les affaires sont compliquées, la logique

    See all articles