Java 如何控制Thymeleaf模板中的有效数字(仅在必要时)?
使用Java 如何控制Thymeleaf模板中的有效数字(仅在必要时)?,java,spring,spring-mvc,thymeleaf,Java,Spring,Spring Mvc,Thymeleaf,使用th:text属性计算和呈现数字字段时,Thymeleaf会显示可用的完整位数。例如,这: <span th:text="${user.averageScore}"/> 我想显示这个数字,四舍五入到小数点后两位以内。从Thymeleaf文档中可以看出: <span th:text="${#numbers.formatDecimal(user.averageScore, 0, 2)}"/> 然而,有没有办法让这更灵活。。。如果该值的小数位数少于两位?我只想去掉小数点
th:text
属性计算和呈现数字字段时,Thymeleaf会显示可用的完整位数。例如,这:
<span th:text="${user.averageScore}"/>
我想显示这个数字,四舍五入到小数点后两位以内。从Thymeleaf文档中可以看出:
<span th:text="${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>
然而,有没有办法让这更灵活。。。如果该值的小数位数少于两位?我只想去掉小数点,减少到两位。我从来不想加小数点,最多两位。如果上述字段的值为107,则它将呈现为:
107.00
我如何制作两位或更少小数的Thymeleaf格式的数字。。。而不是仅仅两位小数,不管怎样?嗨,你可以试试这样的东西
<span th:text="${user.averageScore} % 1 == 0? ${user.averageScore} :${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>
在Thymeleaf 2.1中没有简单的方法可以做到这一点,但有两种困难的方法 艰难之路#1:Fork Thymeleaf并向org.Thymeleaf.expression.Numbers类添加一个格式方法,该方法满足您的需要(添加一个采用十进制格式模式的方法看起来像是一个逻辑扩展) 困难之路#2:向Thymeleaf添加一个方言,该方言提供了一个新的表达式类,可以执行您想要的格式设置。我下面的示例基于使用Spring和Thymeleaf注册一种方言来格式化表示小时的数字 步骤1:注册方言:
@Component
public class ThymeLeafSetup implements InitializingBean {
@Autowired
private SpringTemplateEngine templateEngine;
@Override
public void afterPropertiesSet() throws Exception {
templateEngine.addDialect(new HoursDialect());
}
}
步骤2:创建方言类(委托给TimeUtils静态方法的格式化逻辑)-基于Java8TimeDialante:
public class HoursDialect extends AbstractDialect implements IExpressionEnhancingDialect {
public static class Hours {
public String format(BigDecimal hours) {
return TimeUtils.formatHours(hours);
}
}
@Override
public String getPrefix() {
// No attribute or tag processors, so we don't need a prefix at all and
// we can return whichever value.
return "hours";
}
@Override
public boolean isLenient() {
return false;
}
@Override
public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
return Collections.singletonMap("hours", new Hours());
}
}
步骤4:格式化逻辑测试
@Test
public void formatDecimalWilLFormatAsExpected() {
verifyHourNumberFormatsAsExpected("1.5", "1.5");
verifyHourNumberFormatsAsExpected("1.25", "1.25");
verifyHourNumberFormatsAsExpected("123.0", "123");
verifyHourNumberFormatsAsExpected("1230", "1,230");
}
void verifyHourNumberFormatsAsExpected(String number, String expected) {
assertThat(TimeUtils.formatHours(new BigDecimal(number))).isEqualTo(expected);
}
第二个和第三个参数是什么?
public class HoursDialect extends AbstractDialect implements IExpressionEnhancingDialect {
public static class Hours {
public String format(BigDecimal hours) {
return TimeUtils.formatHours(hours);
}
}
@Override
public String getPrefix() {
// No attribute or tag processors, so we don't need a prefix at all and
// we can return whichever value.
return "hours";
}
@Override
public boolean isLenient() {
return false;
}
@Override
public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
return Collections.singletonMap("hours", new Hours());
}
}
public class TimeUtils {
public static String formatHours(BigDecimal hours) {
DecimalFormat format = new DecimalFormat("#0.##");
format.setGroupingUsed(true);
format.setGroupingSize(3);
return format.format(hours);
}
}
@Test
public void formatDecimalWilLFormatAsExpected() {
verifyHourNumberFormatsAsExpected("1.5", "1.5");
verifyHourNumberFormatsAsExpected("1.25", "1.25");
verifyHourNumberFormatsAsExpected("123.0", "123");
verifyHourNumberFormatsAsExpected("1230", "1,230");
}
void verifyHourNumberFormatsAsExpected(String number, String expected) {
assertThat(TimeUtils.formatHours(new BigDecimal(number))).isEqualTo(expected);
}