ber*_*tie 9 java jsf resourcebundle bean-validation jsf-2
在JSF 2中使用带有BV的resourcebundle看起来像这样:
public class UserBean {
@Size(min=13, message="{creditcard.length}")
public String getCreditCard() {
return this.creditCard;
}
}
Run Code Online (Sandbox Code Playgroud)
我必须在其中一个属性文件中定义ResourceBundle条目,该文件可以在 faces-config.xml
creditcard.length =信用卡长度必须至少为13个字符
我们可以看到creditcard.length的值是非参数化的.
我可以进行参数化的ResourceBundle条目,可以从BV或其他地方填充吗?
这是我想要实现的简单方案:
creditcard.length =信用卡长度必须至少为{0}个字符.感谢您选择{1}信用卡.
而我希望这样的事情:
public class UserBean {
@Size(
min=13,
message="{creditcard.length}",
messageParams={"13", "plantvszombie"})
public String getCreditCard() {
return this.creditCard;
}
}
Run Code Online (Sandbox Code Playgroud)
当验证失败时,creditcard属性的错误消息将显示如下字符串:
信用卡长度必须至少为13个字符.感谢您选择plantvszombie信用卡.
这个ResourceBundle消息参数化是否可行?
请分享您对此事的经验.
谢谢 !
vic*_*era 32
也许您已经知道Bean验证的消息是在ValidationMessages.properties
类的根中的资源包中定义的(即WEB-INF\classes\ValidationMessages.properties
).
这些消息可以有参数,但它们不像JSF那样工作.有一个叫做的接口MessageInterpolator
,它将消息模式转换为实际的消息.
默认插值器使用命名参数,如消息中所示:值必须介于{min}和{max}之间.{和}之间的值首先在应用程序的资源包中解析; 稍后在提供程序的资源包中,最后在约束注释的属性中.(这或多或少是如何工作的,完整的算法在Bean Validation规范的4.3节中).
假设您将Size annotation的属性消息定义为{creditCard.message}
ValidationMessage.properties的内容可以是
creditCard.message=Credit card length must be at least {min} characters. \
Thank you for choosing the plantsvszombies credit card.
Run Code Online (Sandbox Code Playgroud)
你可以用一个属性替换plantsvszombies:
creditCard.message=Credit card length must be at least {min} characters. \
Thank you for choosing the {creditCard.type} credit card.
creditCard.type=plantsvszombies
Run Code Online (Sandbox Code Playgroud)
您甚至可以在约束的消息中使用两个参数
Size(min=13, message="{creditCard.message} {plantsvszombies.messages}")
Run Code Online (Sandbox Code Playgroud)
并将资源包定义为
creditCard.message=Credit card length must be at least {min} characters.
plantsvszombies.message=Thank you for choosing the plantsvszombies credit card.
Run Code Online (Sandbox Code Playgroud)
我认为这是一种简单而干净的方法.
但是如果你想要更多的东西,比如在约束声明中定义自定义参数,你可以使用自定义消息插补器.请注意,这可能是一个棘手的解决方案.
好吧,您可以定义一个语法来在消息字符串中引入您的参数.然后,让默认插值器解析消息.默认插补器不会理解自定义参数的语法,它们在解析后仍然存在.然后,自定义插补器可以替换替换自定义参数.
通过示例更容易理解.
首先,消息定义为{creditCard.message} [plantsvszombies].对于此语法,方括号之间的内容是以逗号分隔的索引参数(此处只有一个参数).
接下来,资源包的内容定义为:
creditCard.message=Credit card length must be at least {min} characters. \
Thank you for choosing the {0} credit card.
Run Code Online (Sandbox Code Playgroud)
当默认插值器替换表达式的第一部分时,我们将:
信用卡长度必须至少为13个字符.\感谢您选择{0}信用卡.[plantsvszombies]
然后,自定义插值器将采用最后一个表达式并拆分内容以获取标记,并使用相应索引中的标记替换索引参数(参数[0] = plantsvzzombies).
所以消息将是:
信用卡长度必须至少为13个字符.\感谢您选择plantsvszombies信用卡.
这是此语法的自定义插值器的代码(未优化,如果第一个表达式或标记中有其他方括号,则正则表达式模式无法工作).
package validation;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.MessageInterpolator;
import javax.validation.Validation;
public class MyInterpolator implements MessageInterpolator{
private MessageInterpolator interpolator;
public MyInterpolator() {
//we need to delegate to the default interpolator
this.interpolator = Validation.byDefaultProvider().configure().getDefaultMessageInterpolator();
}
private static final Pattern parametersPattern=Pattern.compile("\\[(.+)\\]$");
protected static String replaceParameters(String message){
Matcher matcher = parametersPattern.matcher(message);
String values[]={};
if(matcher.find()){
values=matcher.group(1).split("\\s*,\\s*");
message=message.substring(0, matcher.start());
for(int i=0; i < values.length; i++){
message=message.replace("{"+i+"}", values[i]);
}
}
return message;
}
@Override
public String interpolate(String messageTemplate, Context context) {
String message = interpolator.interpolate(messageTemplate, context);
return replaceParameters(message);
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
String message = interpolator.interpolate(messageTemplate, context);
return replaceParameters(message);
}
}
Run Code Online (Sandbox Code Playgroud)
内插器的注册位于名为META-INF/validation.xml(规范的4.4.6)的xml文件中.
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd">
<message-interpolator>validation.MyInterpolator</message-interpolator>
</validation-config>
Run Code Online (Sandbox Code Playgroud)
这是一个有点复杂的解决方案,因为约束注释不接受消息的参数,因为在插值器中,我们无法获得正在验证的属性的许多信息.如果我找到一个更简单的解决方案,我会发布它.
归档时间: |
|
查看次数: |
11576 次 |
最近记录: |