自定义error_messages_for定制校验信息

本文介绍了一个Ruby模块,该模块提供了一种优雅的方式来处理并显示对象的验证错误消息。通过使用此模块,可以轻松地收集和格式化多个对象的错误信息,并将其呈现为易于理解的HTML格式。
ruby 代码
 
  1. module ApplicationHelper  
  2.   def error_messages_for(*params)  
  3.     options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}  
  4.     objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact  
  5.     count   = objects.inject(0) {|sum, object| sum + object.errors.count }  
  6.     unless count.zero?  
  7.       html = {}  
  8.       [:id:class].each do |key|  
  9.         if options.include?(key)  
  10.           value = options[key]  
  11.           html[key] = value unless value.blank?  
  12.         else  
  13.           html[key] = 'errorExplanation'  
  14.         end  
  15.       end  
  16.       header_message = ""#"#{pluralize(count, 'error')} prohibited this #{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from being saved"  
  17.       #error_messages = objects.map {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }  
  18.       error_messages = objects.map do |object|  
  19.         full_messages = []  
  20.         object.errors.each do |attr,msg|  
  21.           full_messages << msg unless msg.nil? || msg.blank?  
  22.         end  
  23.         full_messages.map{|msg| content_tag(:li,msg)}  
  24.       end  
  25.       content_tag(:div,  
  26.         content_tag(options[:header_tag] || :h2, header_message) <<  
  27.           content_tag(:p, '发生以下错误:') <<  
  28.           content_tag(:ul, error_messages),  
  29.         html  
  30.       )  
  31.     else  
  32.       ''  
  33.     end  
  34.   end  
  35. end  
<think>嗯,用户想了解如何在自定义的ConstraintValidator中根据不同的校验结果返回不同的提示信息。首先,我需要回忆一下Bean Validation的相关知识,特别是自定义注解和验证器的流程。 用户提到要根据不同的校验结果提示不同的信息,这意味着同一个约束注解需要能返回多个不同的错误消息。通常,每个ConstraintValidator对应一个注解,而注解的message属性默认只能有一个。那如何实现动态消息呢? 首先,可能需要结合不同的校验条件,在验证器中根据不同的失败情况设置不同的消息。这时候,可能需要用到Hibernate Validator的MessageInterpolator,或者利用ConstraintValidatorContext来动态构建消息。 记得ConstraintValidator的isValid方法有一个ConstraintValidatorContext参数,可以用来构建自定义的错误消息。例如,可以通过context.buildConstraintViolationWithTemplate()方法,针对不同的情况添加不同的错误消息。 接下来,应该分步骤思考如何实现。首先,创建一个自定义的注解,比如@CustomConstraint,然后编写对应的ConstraintValidator实现类。在isValid方法中,根据不同的校验条件,使用context来添加不同的消息模板。 可能还需要在自定义注解中定义多个message属性,或者在验证器内部通过条件判断来动态选择消息。但注解的属性是固定的,无法动态改变,所以应该在验证器中动态设置消息内容。 例如,在验证逻辑中,如果条件A不满足,就使用context构建一个错误消息,指定messageA;如果条件B不满足,就指定messageB。这样,当校验失败时,会根据不同的情况返回不同的消息。 同时,需要考虑如何将这些不同的消息定义在资源文件中,比如ValidationMessages.properties,以便支持国际化和统一管理。这时候,需要在消息模板中使用占位符,或者直接引用资源文件中的键。 另外,可能还需要在自定义注解中添加参数,允许传递不同的消息代码,然后在验证器中根据不同的情况选择对应的参数。但这样可能会让注解变得复杂,不如直接在验证器里处理更灵活。 总结下来,步骤大致是:创建自定义注解、实现ConstraintValidator、在isValid方法中根据校验条件使用ConstraintValidatorContext动态设置错误消息,并确保消息内容来自资源文件或直接指定。最后,通过示例代码展示如何实现这一点,帮助用户理解具体的代码结构。</think>在Spring Validation中实现自定义ConstraintValidator的多消息返回,可通过以下步骤实现: 1. 创建自定义注解 ```java @Target({FIELD, PARAMETER}) @Retention(RUNTIME) @Constraint(validatedBy = StatusValidator.class) public @interface ValidStatus { String message() default "通用错误提示"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; // 可选定义不同场景的错误码 String invalidFormatCode() default "STATUS_INVALID_FORMAT"; String outOfRangeCode() default "STATUS_OUT_OF_RANGE"; } ``` 2. 实现ConstraintValidator ```java public class StatusValidator implements ConstraintValidator<ValidStatus, String> { private String invalidFormatCode; private String outOfRangeCode; @Override public void initialize(ValidStatus constraintAnnotation) { this.invalidFormatCode = constraintAnnotation.invalidFormatCode(); this.outOfRangeCode = constraintAnnotation.outOfRangeCode(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (!Pattern.matches("\\d{3}", value)) { buildCustomViolation(context, invalidFormatCode); return false; } int code = Integer.parseInt(value); if (code < 100 || code > 599) { buildCustomViolation(context, outOfRangeCode); return false; } return true; } private void buildCustomViolation(ConstraintValidatorContext context, String errorCode) { context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate("{" + errorCode + "}") .addConstraintViolation(); } } ``` 3. 配置消息资源文件(ValidationMessages.properties) ```properties STATUS_INVALID_FORMAT=状态码必须是三位数字 STATUS_OUT_OF_RANGE=状态码范围需在100-599之间 ``` 4. 使用方式 ```java public class RequestDTO { @ValidStatus private String statusCode; } ``` 执行校验时会根据不同的失败场景返回对应消息,验证失败示例: - 输入"50a" ➔ "状态码必须是三位数字" - 输入"600" ➔ "状态码范围需在100-599之间" 关键点说明: 1. 通过`ConstraintValidatorContext`禁用默认消息 2. 使用`buildConstraintViolationWithTemplate()`动态指定消息模板 3. 消息模板支持国际化键值(用花括号包裹) 4. 可扩展支持动态参数(通过`addMessageParameter()`方法) 进阶方案:对于需要返回多个错误的情况,可以通过`HibernateConstraintValidator`的`initialize()`方法获取更多上下文信息,结合`@ReportAsSingleViolation`注解控制错误报告方式。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值