如何使用 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 将字符串转换为数字?的主要内容,如果未能解决你的问题,请参考以下文章