自定义表单验证注释不起作用

Posted

技术标签:

【中文标题】自定义表单验证注释不起作用【英文标题】:custom form validation annotation not working 【发布时间】:2017-04-01 17:49:34 【问题描述】:

我创建了一个自定义表单验证注解,用于检查表单中填写的日期是否为 dd/MM/yyyy 格式。不幸的是,它不起作用,验证失败,我尝试的任何日期格式。最初我认为问题在于我用于测试的正则表达式,但在做了一些测试后,我很确定它可以工作。

我错过了什么?这是我的代码(我只复制相关部分),请帮助我理解我做错了什么:

bean Articolo(注意:该类嵌套在模型类 NewEditArticle 中,如下)

@Entity
@Table (name="Articolo")
public class Articolo 

    @Column (name="Data")
    @Temporal (TemporalType.DATE) //match the data type used in DB
    @IsValidDate //check date format is dd/MM/yyyy (custom validator)
    private Date data;

类 IsValidDate

@Documented //mandatory
@Constraint (validatedBy= DateValidator.class) //this class contains the validation logic
@Retention (RetentionPolicy.RUNTIME) //mandatory
public @interface IsValidDate 

    //error message
    String message() default "Please insert date in format dd/mm/yyyy";

    Class <?>[] groups() default ; //mandatory

    Class <? extends Payload> [] payload () default ; //mandatory

类 DateValidator

public class DateValidator implements ConstraintValidator <IsValidDate, Date > 

    @Override
    public void initialize(IsValidDate isValidDate) 
        // TODO Auto-generated method stub

    

    @Override
    public boolean isValid(Date data, ConstraintValidatorContext ctx) 

        //convert Date data to String
        String dateString=data.toString();

        //format dd/MM/yyyy
        String regex="(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";


        if (dateString.matches(regex))
            return true;
        

        //if date doesn't match regex, return error message from IsValidDate
        else 
            return false;
        
    


模型类

public class NewEditArticolo 

    //ATTRIBUTES

    @Valid  //requested to trigger validation of bean Articolo
    private Articolo articolo;

    private List<Area> ListaArea;
    private List<Cucina> ListaCucina;
    private List<Prezzo> ListaPrezzo;
    private List<Voto> ListaVoto;
    private List<String> ListaImg;


    //METHODS

    //CONSTRUCTOR

    //create article model without ID number
    //used in controller POST method
    public NewEditArticolo () 

        populateLists();
    

    //create Article model based on ID number
    //if ID=0 (new Article), creates empty model
    //used in controller GET method
    public NewEditArticolo(int ID) throws SQLException 

        // call DAOArticolo.select only if article already exists
        if (ID != 0) 
            DAOArticolo DAOart = new DAOArticolo();
            articolo = DAOart.select(ID);
        

        populateLists();

    

控制器

public String editArticle ( Model model,
                                @Valid @ModelAttribute (value="nea") NewEditArticolo nea, //create NewEditArticolo object, autowire attributes from ArticleManager.jsp, add to model and validate
                                BindingResult result, //collect validation errors
                                @RequestParam (value="submit") String submit) //get input value from ArticleManager.jsp

        Articolo articolo1=nea.getArticolo();

        DAOArticolo daoArt = new DAOArticolo();

        //if validation fails, return form to display validation errors
        if (result.hasErrors()) 
            System.out.println("VALIDATION FAILED");
            return "ArticleManager";
        

        else 
            System.out.println("VALIDATION WAS SUCCESFULL");
        

Spring-dispatcher-servlet.xml

<bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages" />
    </bean>

【问题讨论】:

你的类路径上是否真的有一个 bean-validation 实现...没有它什么都不会发生。 你的问题解决了吗? 不是真的,我不确定你对 bean 验证实现的意思......你能解释一下吗? 我在帖子中添加了我的 Spring-dispatcher-servlet.xml 【参考方案1】:

您可以在没有 Regex 的情况下做到这一点。 Spring有@DateTimeFormat注解。在您的模型中执行以下操作。

@NotNull(message = "Please enter Birth Date")
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Date birthDate;

您可以添加自定义错误消息。在资源文件夹下创建message.properties。在这个文件里面:

typeMismatch=Invalid date format

重点是将这个添加到配置类中。

@Bean
public MessageSource messageSource() 
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;

【讨论】:

使用您建议的基于注释的验证,我总是会收到默认错误消息,就像忽略 message.properties 文件一样。我的猜测是,自定义错误消息不适用于嵌套对象的验证,就像我的情况一样(bean 类 Article 是模型类 NewEditArticle 的一个字段,它在控制器类中验证并自动连接到表单)。

以上是关于自定义表单验证注释不起作用的主要内容,如果未能解决你的问题,请参考以下文章

材料ui的自定义输入中的Redux表单不起作用

Angular2- RC6 自定义表单控件不起作用

自定义密码匹配验证器在 angular5 中不起作用

模型表单上的 Django 自定义设置大小属性不起作用

带有自定义查询集的表单向导

尝试通过Javascript验证表单,但代码不起作用