Freemarker (FTL) - 如何使用?number检查字符串是否可以转换为数字。

问题描述 投票:0回答:1

如何检查一个字符串是否可以转换为数字?

例如,这将无法工作,除非 SelfAge 是一个有效的字符串来转换。

<#if SelfAge?? && (SelfAge?number > 15)>

测试数据:

SelfAge = "October 30, 1913 // "Can't convert this string to number: "October 30, 1913"
SelfAge = "User-submitted-comment" //  Can't convert this string to number: "User-submitted-comment"
SelfAge = "1/12" // Can't convert this string to number: "1/12"
freemarker
1个回答
0
投票

有2个appraoches。

Freemarker尝试,恢复块

假设输入的内容可以是以下内容之一。

<#assign SelfAge = "October 30, 1913" >
<#assign SelfAge = "1/12" >
<#assign SelfAge = "101" >
<#assign SelfAge = "User-submitted-comment" >

您可以使用以下方法来实现这一点(从2.3.3开始) 试图:

<#attempt>
    <#-- try -->
    <#if SelfAge?? && (SelfAge?number > 15)>
     Will do something with the number
    </#if>

<#recover>
    <#-- catch -->
    Can't convert this string to number: ${SelfAge}
</#attempt>

但是,这个解决方案有局限性。

  • 会引发异常,并在日志中显示为大的错误痕迹。
  • 不支持所有的数字格式,只支持纯数字字符串。

这就导致了第二种更好的方法.

Freemarker TemplateHashModel容器

您可以使用 TemplateHashModel Hash 来创建一个你自己的实用工具类的模型,你可以用它来访问更多的自定义的乐趣,而这些乐趣是Freemarker没有提供的。

我们的目标是创建一个名为 isNumber 在你的项目中的一个名为 MyUtils 然后我们将使用这个方法来检查字符串,并得到true或false。以这种方式。

<#if Utils.isNumber(SelfAge)>

首先,创建你的 MyUtils 类。

package example;
public class MyUtils {

        public static boolean isNumber(String s){
            try {
                Integer.parseInt(s);
                return true;
            }
            catch (NumberFormatException e){
                return false;
            }
        }

    }

第二,实现一个bean包装器来创建静态模型容器,并将你的类添加到其中(确保包路径正确)。

BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel staticModels = wrapper.getStaticModels();
TemplateHashModel myUtilsWrapper = (TemplateHashModel) staticModels.get( "example.MyUtils" );

如果你的应用是Spring应用,包装器可以添加到控制器中,重定向到你的页面,这里是我的控制器类。

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;

    @RestController
    public class HelloController {

            @RequestMapping("/")
            public ModelAndView hello() throws TemplateModelException {
                ModelAndView mainView = new ModelAndView();
                mainView.setViewName("index");

                BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
                TemplateHashModel staticModels = wrapper.getStaticModels();
                TemplateHashModel myUtilsWrapper = (TemplateHashModel) staticModels.get( "example.MyUtils" );

                mainView.getModel().put("Utils", myUtilsWrapper);

                return mainView;
            }

        }

请注意我们如何命名我们的包装器: Utils <--这是我们用来从Freemarker模板中访问方法的名字。

现在在Freemarker中这样做。

<#if Utils.isNumber(SelfAge)>
    <div>Will do something with the number</div>
<#else>
    <div>Can't convert this string to number: ${SelfAge}</div>
</#if>

它将产生与第一种方法相同的输出,但有更好的代码封装。

奖励

我会更进一步,用Apache Commons实现检查器的方法。NumberUtils.isCreatable()

这样一来,零,负前号,以及所有的数字格式都会被覆盖。

public static boolean isNumeric(String s){
    return NumberUtils.isCreatable(s);
}

然后在Freemarker中。

<#if Utils.isNumeric(SelfAge)>
    <div>Will do something with the number</div>
<#else>
    <div>Can't convert this string to number: ${SelfAge}</div>
</#if>

例子:这个例子 <#assign SelfAge = "-101.1" > 在第一次和第二次评估中会失败,但在奖金建议中会有效。

会在数字上做一些事情


0
投票

这适用于非负整数。

[#if ageString?matches("^\\d+$")]
    [#assign ageNumber = ageString?number]
[/#if]
© www.soinside.com 2019 - 2024. All rights reserved.