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

时间:2016-06-13 10:00:11

标签: java jsp freemarker

我是一个较新的开发人员,我正在使用jsp,freemarker和java-ee开展项目。我的问题是我无法通过freemarker将字符串转换为double。我使用带有双输入的表单,如果输入是整数,验证完成没有错误,如果它是带逗号的数字,我得到一个异常说:

FreeMarker模板错误: 无法将此字符串转换为数字:" 43,4"

这是我的模特:

@Table 公共类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)

3 个答案:

答案 0 :(得分: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)!}",

答案 1 :(得分:1)

问题解决了一些系统设置,该号码自动转换为带逗号的frensh格式。 Freemarker的解析器不会识别带有逗号的double作为double,因此我更改了Regional和Language&gt;格式下的格式。这很好,谢谢你。

答案 2 :(得分:0)

conversionRate看起来不像是double值。它显示为43,4.它应该是43.5或435.So请检查balanceConfig.conversionRate中的值。