使用@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
转换器(深入检查代码绝对是多余的).
I have the following general BigDecimal
converter (deeply reviewing the code is absolutely superfluous).
@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).也可以在需要时定义其他标准,即不需要其他类型的格式的单独转换器(如果有).转换器的默认任务是将值四舍五入到小数点后两位.
Depending upon the value of variant
in <f:attribute>
, it converts the value to either currency equivalent ($123) or a value using groups (11,111). Other criteria may also be defined as and when required i.e separate converters for other types of formats, if any, are not required. The default task of the converter is to round up the value to two decimal points.
为了避免提及,
<f:converter converterId="bigDecimalConverter"/>
或converter="#{bigDecimalConverter}"
到处都是,转换器类需要装饰,
or converter="#{bigDecimalConverter}"
everywhere, the converter class needs to be decorated with,
@FacesConverter(forClass = BigDecimal.class)
这样做,JSF拥有自己的 javax.faces.convert.BigDecimalConverter
提前.我尝试过扩展该类,但没有任何区别.
Doing so, JSF takes its own javax.faces.convert.BigDecimalConverter
beforehand. I have tried extending that class but it did not make any difference.
是否可以覆盖默认的JSF javax.faces.convert.BigDecimalConverter
,以便通过指定forClass = BigDecimal.class
来使用我们自己的转换器,从而无需在任何地方乱搞<f:converter converterId="bigDecimalConverter"/>
或converter="#{bigDecimalConverter}"
?
Is it possible to override the default JSF javax.faces.convert.BigDecimalConverter
so that our own converter can be used by specifying forClass = BigDecimal.class
so that there is no need to fiddle around with <f:converter converterId="bigDecimalConverter"/>
or converter="#{bigDecimalConverter}"
anywhere?
推荐答案
通常,覆盖默认转换器(以及验证器,组件和渲染器)时,不能在同一标识符上使用注释.它确实必须在Webapp自己的faces-config.xml
中明确注册.
In general, overriding default converters (and validators, components and renderers) can't take place with annotations on the same identifier(s). It really has to be explicitly registered in webapp's own faces-config.xml
.
如果您打算覆盖converter="javax.faces.BigDecimal"
,请这样做:
In case you intend to override converter="javax.faces.BigDecimal"
, then do so:
<converter>
<converter-id>javax.faces.BigDecimal</converter-id>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
如果您打算覆盖类型java.math.BigDecimal
的隐式转换,请这样做:
In case you intend to override implicit conversion for type java.math.BigDecimal
, then do so:
<converter>
<converter-for-class>java.math.BigDecimal</converter-for-class>
<converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>
您需要后者.
这篇关于使用@FacesConverter(forClass = BigDecimal.class)覆盖JSF转换器javax.faces.convert.BigDecimalConverter以便使用自定义转换器.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!