ValidationMessages.properties 文件之间的冲突

2024-01-04

我习惯将所有验证约束收集在一个公共库中。在罐子的根部我放了一个ValidationMessages_it.properties文件。 一切正常,如果我将此库放入 jsf 2 war 项目中,所有验证消息都会正确显示。 但是,如果我再放一个,就会出现问题ValidationMessages_it.properties战争神器中也是如此。在这种情况下{library.message_key}显示字符串。

我认为 Bean Validation 在战争中找到了正确的属性文件,并且没有考虑到库中的属性文件。 我该如何解决?

Example

我有一个库 commons.jar,其中包含自定义约束。为了设置这些约束的消息,我添加了一个ValidationMessages_it.properties在这个库的根目录中

commons.jar
    |
    + library
    |   |
    |   + CustomConstraint.class
    |
    + ValidationMessages_it.properties

ValidationMessages_it.properties

library.custom=Questo è l'errore di cui parlavo

自定义约束.java

@Pattern( regexp = "[a-z]", message = "{library.custom}" )
@Constraint( validatedBy = {} )
@Documented
@Target( { ElementType.METHOD, ElementType.FIELD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface CustomConstraint {
    String message() default "C'è un errore";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

PS: 请注意,消息键位于 @Pattern 注释上,而不是 message() 上,这可能看起来是一个错误,但否则它永远不会起作用!

之后我想用这个commons.jar在我的网络应用程序项目(jsf/mojarra 2.1)中。一切正常。显示的错误消息是“Questo è l'errore di cui parlavo”。

但现在假设我在 web 应用程序中定义了新的验证约束,因此我想通过添加ValidationMessages_it.properties in WEB-INF/classes文件夹。在这种情况下,显示的错误消息是“{library.custom}”

所以我认为 BV(或 jsf?)在战争中找到了捆绑包,并且没有考虑到 commons.jar 中的捆绑包。它没有找到钥匙library.custom in the ValidationMessages_it.properties位于WEB-INF/classes文件夹从而返回{library.custom}字面上地。

实施例2

基于共享库中的 Bean 验证约束 https://stackoverflow.com/questions/11683708/bean-validation-constraints-in-a-shared-library,我的包结构似乎是正确的。我上传了一个简单的网络应用程序来显示问题:

  • 可以部署在符合 java EE 6 的应用程序服务器中的战争工件 http://www.filefactory.com/file/1v4e61w0ty77/n/bvtest-1_0_war
  • 包含两个 Maven 项目的源 zip,一个用于库,一个用于 Web 应用程序 http://www.filefactory.com/file/1iteiatld9of/n/bvsource_zip

我在 Glassfish 3.1.2、JBoss AS 7.1.1、Geronimo 3.0.0 中测试了 web 应用程序

Glassfish 和 JBoss 具有相同的行为。在 Geronimo 中,它的效果要好一些。


默认情况下,如果有多个 JAR/WAR/等。文件包含一个同名的资源包文件,只有其中一个将用于验证器消息。这就是这里的问题:两者commons.jar并且应用程序 WAR 包含一个名为ValidationMessages_it.properties.

Hibernate Validator 5.2 于 2015 年 7 月发布,增加了对聚合来自不同 JAR 文件的所有同名资源包的支持。该功能默认是禁用的,可以在org.hibernate.validator.resourceloading.PlatformResourceBundleLocator http://docs.jboss.org/hibernate/validator/5.2/api/org/hibernate/validator/resourceloading/PlatformResourceBundleLocator.html#PlatformResourceBundleLocator-java.lang.String-java.lang.ClassLoader-boolean-.

Example:

PlatformResourceBundleLocator resourceBundleLocator =
        new PlatformResourceBundleLocator(
                ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, 
                null, true);

Validator validator = Validation.byProvider(HibernateValidator)
    .configure()
    .messageInterpolator(
            new ResourceBundleMessageInterpolator(resourceBundleLocator))
    .buildValidatorFactory()
    .getValidator();

使用 Java 配置的 Spring 项目的等效代码:

@Bean
public LocalValidatorFactoryBean validator() {
    PlatformResourceBundleLocator resourceBundleLocator =
            new PlatformResourceBundleLocator(
                    ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, 
                    null, true);

    LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
    factoryBean.setMessageInterpolator(
            new ResourceBundleMessageInterpolator(resourceBundleLocator));
    return factoryBean;
}

对于使用 Web MVC 的 Spring Boot 3.x 项目,以下配置了 Spring 使用的默认验证器,以及 Web MVC 用于验证控制器参数等的验证器:

import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class ValidationConfig {
    /**
     * Matches the bean name from {@code ValidationAutoConfiguration.defaultValidator}.
     */
    @Bean
    public LocalValidatorFactoryBean defaultValidator() {
        PlatformResourceBundleLocator resourceBundleLocator =
                new PlatformResourceBundleLocator(
                        ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, 
                        null, true);

        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        factoryBean.setMessageInterpolator(
                new ResourceBundleMessageInterpolator(resourceBundleLocator));
        return factoryBean;
    }

    @Bean
    public WebMvcConfigurer validatorConfigurer(Validator defaultValidator) {
        return new WebMvcConfigurer() {
            @Override
            public Validator getValidator() {
                return defaultValidator;
            }
        };
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ValidationMessages.properties 文件之间的冲突 的相关文章

随机推荐

  • Android在没有edittext视图的情况下捕获硬件键盘事件

    如何在不使用 EditText 字段的情况下捕获硬件键盘事件 例如 在一个简单的活动中 在屏幕上显示一个正方形 当在滑动键盘上按下 B 时 我想将其变为蓝色 当按下 G 时 将其变为绿色 等等 我不需要颜色代码的帮助 只需要如何拦截按键 这
  • 修改后的 baugh-wooley 算法乘法 verilog 代码不能正确乘法

    以下 verilog 源代码和 或测试平台可以很好地工作商业模拟器 iverilog https www edaplayground com x 3TuQ也形式化验证工具 yosys smtbmc https gist github com
  • ASP 服务器端代码如何损坏智能引用?

    我的公司刚刚将许多列从 varchar 转换为 nvarchar 现在看来 当我们将智能引号 即 ALT 0146 渲染到屏幕上 然后将其发送回 SQL Server 2000 数据库进行持久化时 智能引号会被损坏为 我的问题 ASP 服务
  • Paypal IPN 响应无法进入 Android 移动浏览器

    我是 Paypal 集成的新手 我正在尝试为我的 Android 应用程序实现 Paypal IPN 为了使其正常工作 我创建了一个网页 使用 PHP 并发送到 Paypal 沙箱帐户 方法 GET 以便我进行付款 我正在从中获取付款状态
  • 如何在C#中使用C++ DLL导出的接口指针

    我有一个用 C 编写的 DLL 它导出一个函数 CreateRisk 该函数返回一个接口指针 如下 extern C declspec dllexport IRisk stdcall CreateRisk return new Risk I
  • Sweet Alert 带有 href 的删除确认

    我使用 PHP 和 Sweet Alert 进行删除确认 问题是它在显示甜蜜警报之前就被删除了 这是我的 HTML 其中使用 PHP div class delete a href i class far fa trash alt i a
  • 值构造函数的别名

    是否可以为值构造函数定义别名 上下文是这样的 我正在编写一个程序 它将原始递归函数实现为图灵机 为此 我正在使用一元整数编码 我的图灵机类型定义如下 definition of a Turing machine data TuringMac
  • WSFederationAuthenticationModule v/s SessionAuthenticationModule

    根据文档 这两个模块都将用于创建 IClaimsPrincipal 的实例 我不明白为什么 WIF 费心使用 2 个 HttpModules 而不是 1 个 抱歉 我是 WIF 新人 最大的区别在于 WSFederationAuthenti
  • 禁用 JShell 历史记录

    默认情况下 JShell 启用所有键入内容的持久历史记录 可以通过按向上箭头来调用 关闭此 功能 的设置在哪里 另外 我如何清除当前历史记录 也许我比较笨 但是我不明白这个命令 reset似乎什么也没做 另外 我如何清除当前历史记录 我提出
  • 为什么用Java VisualVM监控Tomcat时堆空间不断增大?

    我有一个在 Tomcat 中运行的 JRubyOnRails 应用程序 浏览到我的应用程序 localhost 登录然后什么都不做后 堆空间似乎在不断增长 这正常吗 如果我按 执行 GC 它会再次下降 我想知道如果我将其保留到其达到计算机
  • Findbugs android gradle 插件

    我有一个安卓项目 我想介绍findbugs在我的项目中作为 gradle 插件 我尝试编辑项目的build gradle如下 buildscript repositories mavenCentral maven url https mav
  • Intent.EXTRA_EMAIL 未填充“收件人”字段

    我正在尝试使用intent questions tagged intent从我的应用程序发送电子邮件 但电子邮件的 收件人 字段不会填充 如果我添加代码来填写主题或文本 它们就可以正常工作 仅 收件人 字段不会填充 我也尝试将类型更改为 t
  • 从文件中的每一行创建一个字典

    我正在尝试从这个文件创建一个字典 键是第一个单词 值是后面的所有单词 andrew fred fred judy andrew fred george judy andrew john george 这是我的代码 follows file
  • AngularJS - 启用 HTML5 模式页面刷新而不会出现 404 错误 [重复]

    这个问题在这里已经有答案了 我也尝试通过设置 locationProvider html5Mode true 在 ui routing 和 base href 中它删除了哈希值 但在刷新时它给出了404错误 请帮帮我 正如其他人所说 启用
  • 在重复的动态类型部分视图中从匿名类型属性发出 HTML 字符串

    我将匿名类型传递到动态部分视图中作为 model 其中一个属性是包含一些 HTML 的字符串 当我使用HtmlHelper方法来呈现属性 Razor 引擎正在对字符串进行编码 从而在页面上生成文字文本 i text i 在这种情况下 而不是
  • PowerShell 舍入和格式浮点到最多 2 位小数?

    我发现了很多东西可以将浮点数格式化为常见的已知数字 但是如何将浮点数格式化为最多 2 位小数 但前提是需要小数 例子 1 11 not 1 111 1 12 it was 1 116 round up 1 1 not 1 10 1 not
  • 逐行比较 2 个数据帧的随时间分析

    这是我正在使用的数据框的一小部分 以供参考 https i stack imgur com 7fdwL jpg我正在 R 中使用一个数据框 MG53 HanLab 其中有一列时间 几列名称为 MG53 的列 几列名称为 F2 的列以及几列名
  • 有没有办法让 git 忽略整个分支?

    这可能违背了 git 的设计理念 但是 在我的组织中 我不断地删除数千个开发人员分支 例如Dev
  • std 函数 std::_Rb_tree_rebalance_for_erase () 中的分段错误

    请注意未来的读者 不出所料 错误出现在我的代码中 而不是 std Rb tree rebalance for erase 我对编程有点陌生 不确定如何处理似乎来自 std 函数的分段错误 我希望我做了一些愚蠢的事情 即滥用容器 因为我不知道
  • ValidationMessages.properties 文件之间的冲突

    我习惯将所有验证约束收集在一个公共库中 在罐子的根部我放了一个ValidationMessages it properties文件 一切正常 如果我将此库放入 jsf 2 war 项目中 所有验证消息都会正确显示 但是 如果我再放一个 就会