如何使用 freemarker 将字符串转换为数字?

Posted

技术标签:

【中文标题】如何使用 freemarker 将字符串转换为数字?【英文标题】:How can I convert a string to number with freemarker? 【发布时间】:2016-10-13 16:45:24 【问题描述】:

我是一个较新的开发者,我正在使用 jsp、freemarker 和 java-ee 开发一个项目。我的问题是我无法使用 freemarker 将字符串转换为双精度。我正在使用带有双输入的表单,如果输入是整数,则验证完成而没有错误,如果是带逗号的数字,我会收到一个异常:

FreeMarker 模板错误: 无法将此字符串转换为数字:“43,5”

这是我的模型:

@表 公共类 BalanceConfig 扩展 BaseObject 实现 Serializable

@Id(sequence = "SEQ_BALANCE_CONFIG")
@SearchCriteria
protected Long id;

@ManyToOne
@SearchCriteria
private Balance balance;

@OneToMany(clazz = BalanceConfigProfile.class, cascade = CascadeType.REMOVE)
@SearchCriteria
private List<BalanceConfigProfile> balanceConfigProfiles;

@OneToMany(clazz = BalanceUsage.class, cascade = CascadeType.REMOVE)
@SearchCriteria
private List<BalanceUsage> balanceUsages;

@Column
@SearchCriteria
private Long balanceId;

@Column
@SearchCriteria(type = SearchCriteriaType.LIKE)
private String name;

@Column
@SearchCriteria
private String unit;

@Column
@SearchCriteria
private String family;

@Column
@SearchCriteria
private Double conversionRate;

@Column
@SearchCriteria
private Integer priority;

@Column
@SearchCriteria
private Date startDate;

@Column
@SearchCriteria
private Date endDate;

@Column
@SearchCriteria
private Boolean zeroVisibility;

@Column
@SearchCriteria
private Boolean portailVisibility;

@Column
@SearchCriteria
private Boolean crmVisibility;

@Column
@SearchCriteria
private Boolean selfcareVisibility;

@Column
@SearchCriteria
private Boolean endDateVisibility;

@Column
@SearchCriteria
private Boolean defaultConfig;

getters and setters;

模板是:


    "id"                    : "$balanceConfig.id",
    "balanceId"             : "$balanceConfig.balanceId",
    "balanceCode"           : "$balanceConfig.balance.code",
    "name"                  : "<#if balanceConfig.name??>$balanceConfig.name?json_string</#if>",
    "unit"                  : "<#if balanceConfig.unit??>$balanceConfig.unit?json_string</#if>",
    "family"                : "<#if balanceConfig.family??>$balanceConfig.family?json_string</#if>",
    "conversionRate"        : "<#if balanceConfig.conversionRate??>$balanceConfig.conversionRate?number</#if>",
    "priority"              : "<#if balanceConfig.priority??>$balanceConfig.priority?number</#if>",
    "startDate"             : "<#if balanceConfig.startDate??>$balanceConfig.startDate?date</#if>",
    "endDate"               : "<#if balanceConfig.endDate??>$balanceConfig.endDate?date</#if>",
    "zeroVisibility"        : "<#if balanceConfig.zeroVisibility??>$balanceConfig.zeroVisibility?string</#if>",
    "portailVisibility"     : "<#if balanceConfig.portailVisibility??>$balanceConfig.portailVisibility?string</#if>",
    "crmVisibility"         : "<#if balanceConfig.crmVisibility??>$balanceConfig.crmVisibility?string</#if>",
    "selfcareVisibility"    : "<#if balanceConfig.selfcareVisibility??>$balanceConfig.selfcareVisibility?string</#if>",
    "endDateVisibility"     : "<#if balanceConfig.endDateVisibility??>$balanceConfig.endDateVisibility?string</#if>",
    "defaultConfig"         : "<#if balanceConfig.defaultConfig??>$balanceConfig.defaultConfig?string</#if>"

这里是个例外:

FreeMarker template error:
Can't convert this string to number: "43,5"
The blamed expression:
==> balanceConfig.conversionRate?number  [in template "balanceconfig.ftl" at line 8, column 70]

The failing instruction (FTL stack trace):
----------
==> $balanceConfig.conversionRate?number  [in template "balanceconfig.ftl" at line 8, column 68]
----------

Java stack trace (for programmers):
----------
freemarker.core.NonNumericalException: [... Exception message was already printed; see it above ...]
    at freemarker.core.NonNumericalException.newMalformedNumberException(NonNumericalException.java:98)
    at freemarker.core.StringBuiltins$numberBI.calculateResult(StringBuiltins.java:223)
    at freemarker.core.StringBuiltins$StringBuiltIn._eval(StringBuiltins.java:87)
    at freemarker.core.Expression.eval(Expression.java:111)
    at freemarker.core.Expression.evalAndCoerceToString(Expression.java:115)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
    at freemarker.core.Environment.visitByHiddingParent(Environment.java:286)
    at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:86)
    at freemarker.core.Environment.visit(Environment.java:265)
    at freemarker.core.MixedContent.accept(MixedContent.java:93)
    at freemarker.core.Environment.visit(Environment.java:265)
    at freemarker.core.Environment.process(Environment.java:243)
    at freemarker.template.Template.process(Template.java:277)

【问题讨论】:

【参考方案1】:

问题是您已经在balanceConfig.conversionRate 中有一个号码(等等)。因为?number 被定义为内置字符串,它的左侧操作数会自动转换为字符串(类似于?upper_case 等会这样做)。然后?number 尝试将该字符串解析为一个数字。所以这是一个不必要的来回转换,它充其量什么都不做。但是,它也可能失败。 FreeMarker 转换为国际化格式(在locale 集合中使用逗号作为小数分隔符),而?number 专门用于解析计算机格式字符串(例如XS 类型)。

所以,我认为你应该这样写:

<#-- These you could do outside the template, in configuration: -->
<#setting number_format="computer">
<#setting date_format="iso">
<#setting datetime_format="iso">
<#setting time_format="iso">
...
"family"                : "$(balanceConfig.family?json_string)!",
"conversionRate"        : "$balanceConfig.conversionRate!",
"priority"              : "$balanceConfig.priority!",
"startDate"             : "$(balanceConfig.startDate?date)!",

【讨论】:

通过一些系统设置解决了问题,数字自动转换为带逗号的法语格式。 Freemarker 的解析器无法将带逗号的双精度数识别为双精度数,因此我更改了区域和语言 > 格式下的格式。很好用,谢谢。【参考方案2】:

通过一些系统设置解决了问题,数字自动转换为带逗号的法语格式。 Freemarker 的解析器无法将带逗号的双精度数识别为双精度数,因此我更改了区域和语言 > 格式下的格式。很好用,谢谢。

【讨论】:

+ 来自我 .. 这太棒了,我已经找了 3 天了【参考方案3】:

conversionRate 看起来不像双精度值。它显示 43,5。它应该是 43.5 或 435。所以请检查 balanceConfig.conversionRate 中的值。

【讨论】:

即使我输入带点的双精度数,该数字也会自动转换为带逗号的双精度数。如何配置 json 响应以使用点加倍?

以上是关于如何使用 freemarker 将字符串转换为数字?的主要内容,如果未能解决你的问题,请参考以下文章

FreeMarker 将带逗号的字符串转换为数字

在 FreeMarker 中测试字符串是不是可以转换为数字

Freemarker:将日期从科学记数法转换为数字

使用 Freemarker 将字符串转换为布尔值

如何在freemarker中将日期转换为字符串?

在 Freemarker 中将字符串转换为 JSON