使用 @FacesConverter(forClass = BigDecimal.class) 覆盖 JSF 转换器 javax.faces.convert.BigDecimalConverter 以支持自定义转换器
Overriding the JSF converter javax.faces.convert.BigDecimalConverter in favor of a custom converter using @FacesConverter(forClass = BigDecimal.class)
我有以下通用BigDecimal
转换器(深入审查代码绝对是多余的)。
@FacesConverter(value = "bigDecimalConverter")
public class BigDecimalConverter implements Converter {
@Inject
private CurrencyRateBean currencyRateBean; // Maintains a currency selected by a user in his/her session.
private static final int scale = 2; // Taken from an enum.
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (!StringUtils.isNotBlank(value)) {
return null;
}
try {
BigDecimal bigDecimal = new BigDecimal(value);
return bigDecimal.scale() > scale ? bigDecimal.setScale(scale, RoundingMode.HALF_UP).stripTrailingZeros() : bigDecimal.stripTrailingZeros();
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
BigDecimal newValue;
if (value instanceof Long) {
newValue = BigDecimal.valueOf((Long) value);
} else if (value instanceof Double) {
newValue = BigDecimal.valueOf((Double) value);
} else if (!(value instanceof BigDecimal)) {
throw new ConverterException("Message");
} else {
newValue = (BigDecimal) value;
}
final String variant = (String) component.getAttributes().get("variant");
if (variant != null) {
if (variant.equalsIgnoreCase("grouping")) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
formatter.setGroupingUsed(true);
formatter.setMinimumFractionDigits(scale);
formatter.setMaximumFractionDigits(scale);
return formatter.format(newValue);
} else if (variant.equalsIgnoreCase("currency")) {
String currency = currencyRateBean.getCurrency();
DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("en", new String(currency.substring(0, 2))));
formatter.setDecimalFormatSymbols(formatter.getDecimalFormatSymbols());
formatter.setCurrency(Currency.getInstance(currency));
return formatter.format(newValue);
}
}
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
formatter.setGroupingUsed(false); // Not necessary.
formatter.setMinimumFractionDigits(scale);
formatter.setMaximumFractionDigits(scale);
return formatter.format(newValue);
}
}
可以按如下方式使用。
<h:outputText value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
<f:attribute name="variant" value="grouping"/>
</h:outputText>
根据 <f:attribute>
中 variant
的值,它将值转换为等值货币 ($123) 或使用组 (11,111) 的值。其他标准也可以在需要时定义,即不需要其他类型格式的单独转换器(如果有的话)。转换器的默认任务是将值四舍五入到小数点后两位。
为了避免提及,
<f:converter converterId="bigDecimalConverter"/>
或converter="#{bigDecimalConverter}"
到处,转换器class需要装饰,
@FacesConverter(forClass = BigDecimal.class)
这样做,JSF 会预先获取自己的 javax.faces.convert.BigDecimalConverter
。我试过扩展 class 但它没有任何区别。
是否可以覆盖默认的 JSF javax.faces.convert.BigDecimalConverter
以便我们自己的转换器可以通过指定 forClass = BigDecimal.class
来使用,这样就不需要 fiddle 和 [=23] =] 或 converter="#{bigDecimalConverter}"
任何地方?
更换默认转换器应遵循以下步骤:
扩展您计划替换的默认转换器,以避免 class 转换异常。在您的情况下,这将是 javax.faces.convert.BigDecimalConverter
在 faces-config.xml 中注册您的转换器,指定对应于默认值的 <converter-id>
。这允许您覆盖默认值。您将获得的效果是:
<converter>
<converter-class>
com.you.YourBigDecimalConverter
</converter-class>
<converter-id>
javax.faces.BigDecimal
</converter-id>
</converter>
一般来说,覆盖默认转换器(以及验证器、组件和渲染器)不能用相同标识符上的注释来实现。它确实必须在 webapp 自己的 faces-config.xml
.
中显式注册
如果您打算覆盖 converter="javax.faces.BigDecimal"
,请这样做:
<converter>
<converter-id>javax.faces.BigDecimal</converter-id>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
如果您打算覆盖类型 java.math.BigDecimal
的隐式转换,那么请这样做:
<converter>
<converter-for-class>java.math.BigDecimal</converter-for-class>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
你需要后者。
我有以下通用BigDecimal
转换器(深入审查代码绝对是多余的)。
@FacesConverter(value = "bigDecimalConverter")
public class BigDecimalConverter implements Converter {
@Inject
private CurrencyRateBean currencyRateBean; // Maintains a currency selected by a user in his/her session.
private static final int scale = 2; // Taken from an enum.
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (!StringUtils.isNotBlank(value)) {
return null;
}
try {
BigDecimal bigDecimal = new BigDecimal(value);
return bigDecimal.scale() > scale ? bigDecimal.setScale(scale, RoundingMode.HALF_UP).stripTrailingZeros() : bigDecimal.stripTrailingZeros();
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
BigDecimal newValue;
if (value instanceof Long) {
newValue = BigDecimal.valueOf((Long) value);
} else if (value instanceof Double) {
newValue = BigDecimal.valueOf((Double) value);
} else if (!(value instanceof BigDecimal)) {
throw new ConverterException("Message");
} else {
newValue = (BigDecimal) value;
}
final String variant = (String) component.getAttributes().get("variant");
if (variant != null) {
if (variant.equalsIgnoreCase("grouping")) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
formatter.setGroupingUsed(true);
formatter.setMinimumFractionDigits(scale);
formatter.setMaximumFractionDigits(scale);
return formatter.format(newValue);
} else if (variant.equalsIgnoreCase("currency")) {
String currency = currencyRateBean.getCurrency();
DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("en", new String(currency.substring(0, 2))));
formatter.setDecimalFormatSymbols(formatter.getDecimalFormatSymbols());
formatter.setCurrency(Currency.getInstance(currency));
return formatter.format(newValue);
}
}
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
formatter.setGroupingUsed(false); // Not necessary.
formatter.setMinimumFractionDigits(scale);
formatter.setMaximumFractionDigits(scale);
return formatter.format(newValue);
}
}
可以按如下方式使用。
<h:outputText value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
<f:attribute name="variant" value="grouping"/>
</h:outputText>
根据 <f:attribute>
中 variant
的值,它将值转换为等值货币 ($123) 或使用组 (11,111) 的值。其他标准也可以在需要时定义,即不需要其他类型格式的单独转换器(如果有的话)。转换器的默认任务是将值四舍五入到小数点后两位。
为了避免提及,
<f:converter converterId="bigDecimalConverter"/>
或converter="#{bigDecimalConverter}"
到处,转换器class需要装饰,
@FacesConverter(forClass = BigDecimal.class)
这样做,JSF 会预先获取自己的 javax.faces.convert.BigDecimalConverter
。我试过扩展 class 但它没有任何区别。
是否可以覆盖默认的 JSF javax.faces.convert.BigDecimalConverter
以便我们自己的转换器可以通过指定 forClass = BigDecimal.class
来使用,这样就不需要 fiddle 和 [=23] =] 或 converter="#{bigDecimalConverter}"
任何地方?
更换默认转换器应遵循以下步骤:
扩展您计划替换的默认转换器,以避免 class 转换异常。在您的情况下,这将是
javax.faces.convert.BigDecimalConverter
在 faces-config.xml 中注册您的转换器,指定对应于默认值的
<converter-id>
。这允许您覆盖默认值。您将获得的效果是:<converter> <converter-class> com.you.YourBigDecimalConverter </converter-class> <converter-id> javax.faces.BigDecimal </converter-id> </converter>
一般来说,覆盖默认转换器(以及验证器、组件和渲染器)不能用相同标识符上的注释来实现。它确实必须在 webapp 自己的 faces-config.xml
.
如果您打算覆盖 converter="javax.faces.BigDecimal"
,请这样做:
<converter>
<converter-id>javax.faces.BigDecimal</converter-id>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
如果您打算覆盖类型 java.math.BigDecimal
的隐式转换,那么请这样做:
<converter>
<converter-for-class>java.math.BigDecimal</converter-for-class>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
你需要后者。