gpt4 book ai didi

java - JSF 不正确的 BigDecimal 转换

转载 作者:行者123 更新时间:2023-11-30 04:30:53 26 4
gpt4 key购买 nike

问题:需要通过 JSF 格式化 BigDecimal,但 JSF 破坏了 BigDecimal 的精度。

JSF:

<h:outputText value="#{webUtilMB.roundUp(indexPrice.percentage, 2)}"/>

Java:

public class IndexPrice {
public BigDecimal getPercentage(){ return new BigDecimal("1.325"); }
}

@ManagedBean("webUtilMb")
public class WebUtilManagedBean{
public BigDecimal roundUp(BigDecimal dbvalue, int scale){
return dbvalue.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
}
}

WebUtilManagedBean.roundUp 方法中有一个断点,显示“dbvalue”是“1.3249999999999999555910790149937383830547332763671875”,而不是“1.325”。

然后我用以下方法重载了 WebUtilManagedBean 中的 roundUp 方法:

public Double roundUp(Double dvalue, int scale){
System.out.println(dvalue);
}

当这个重载方法中出现断点时,令我惊讶的是: -“dvalue”是“1.325”,这是正确的。 - 该方法实际上被调用,而不是 roundUp(BigDecimal, int) 方法。

我后来尝试了 BigDecimal 构造函数,得到了以下结果:

BigDecimal db1 = new BigDecimal("1.325"); -> 1.325
BigDecimal db2 = new BigDecimal(1.325d); -> 1.3249999999999999555910790149937383830547332763671875
<小时/>

理论:从上面看来,JSF 似乎正在将我的 BigDecimal 值转换为 String,而不是 Double,然后在该值上调用“new BigDecimal(double)”来获取 BigDecimal - 这会返回错误的值.

<小时/>

修复:解决此问题的一种方法是使用以下代码:

@ManagedBean("webUtilMb")
public class WebUtilManagedBean{
public Double roundUp(Double dvalue, int scale){
return this.roundUp(**new BigDecimal(dvalue.toString())**, BigDecimal.ROUND_HALF_UP);
}
public BigDecimal roundUp(BigDecimal dbvalue, int scale){
return dbvalue.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
}
}

但这对我来说似乎是一种黑客行为。

有关解决此问题的任何想法及其背后的原因。谢谢。

最佳答案

理想情况下,如果 f:convertNumber 有“舍入”属性,则可以通过 f:convertNumber 完成此操作,但事实并非如此。

执行此操作的简洁方法是编写您自己的 roundup f:converter 类,并在 XHTML 中适当的位置使用 f:converter 标记,而不是使用 EL 方法调用。您的转换器将获取对象形式的值,即 BigDecimal,并负责将其转换为字符串本身。请参阅 f:converter 的文档。令人惊讶的是 JSF 没有正确执行此操作,但我想一旦您进入 EL 方法调用,一切都是字符串。像这样的东西(警告:未经测试):

import java.math.BigDecimal;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

/**
* Use via e.g.:
* <pre>
* &lt;h:outputText value="#{EL}"&gt;
* &lt;f:converter id="com.edsi.jsf.RoundHalfUp"/&gt;
* &lt;f:attribute name="decimalPlaces" value="2"/&gt;
* &lt;/h:outputText&gt;
* <pre>
* @author Esmond Pitt
*/
@FacesConverter(value="com.edsi.jsf.RoundHalfUp")
public class RoundHalfUpConverter implements Converter
{

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
BigDecimal bd = (BigDecimal)value;
int decimalPlaces;
try
{
decimalPlaces = Integer.parseInt((String)component.getAttributes().get("decimalPlaces"));
}
catch (Exception exc)
{
decimalPlaces = 2; // or whatever
}
return bd.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).toString();
}

}

关于java - JSF 不正确的 BigDecimal 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14679879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com