文档章节

freemarker的classic_compatible设置,解决报空错误

宇宙星星
 宇宙星星
发布于 2017/08/01 10:39
字数 1396
阅读 44
收藏 0

前段时间接触freemaker时,本来后端写各接口运行正常,但加入了模板后,频繁报空指针问题,整了许久,最后还是请教了别人解决了这个问题,现在记录下来,方便以后碰到了可以查阅。

错误样例如下:

ERROR: freemarker.runtime - Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> user  [in template "include/header.ftl" at line 4, column 14]
 
----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
 
----
FTL stack trace ("~" means nesting-related):
    - Failed at: #if user  [in template "include/header.ftl" at line 4, column 9]
    - Reached through: #include "/include/header.ftl"  [in template "index.ftl" at line 6, column 1]
----
 
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
    at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:131)
    at freemarker.core.UnexpectedTypeException.newDesciptionBuilder(UnexpectedTypeException.java:77)

可以看到,在读取user的时候,因为为空,报错了,错误处的代码是这样的

<#if user>

其实准确的写法应该是

<#if user??>

如果要消除错误,需要把前端代码修后成后面这种形式,这让一个后端开发的人来说很不合理啊,而且,模板中不止一处出现了这种写法。

请教以后把freemarker的配置修改如下:

<bean id="freemarkerConfig"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/template/" />
        <property name="freemarkerSettings">
            <!-- 设置默认的编码方式,原先是GBK,需要设置成utf-8 -->
            <props>
                    <!--用于解决前端报空指针问题-->
                <prop key="classic_compatible">true</prop>
                <prop key="defaultEncoding">utf-8</prop>
                <prop key="template_exception_handler">rethrow</prop>
            </props>
        </property>
    </bean>

添加了一行

<prop key="classic_compatible">true</prop>

问题圆满解决了。

从网上查找原因,发现下面这位哥们已经比较详细的解释了,就全文摘录吧。

以下为转载内容,点击查看原文

        在freemarker中的空值的处理,默认情况以${xxx}的方式取值会报错,我们一般都采用${xxx?if_exists} 的方式去处理,烦死人了。经过查资料,很多人都建议使用classic_compatible=true的方式来处理,目测单词的意思应该是:“兼容传统模式”的意思。但是经过使用发现这个属性设置为true时,也有很多其他问题,比如boolean值的处理,比如include指令必须使用绝对路径,总之也会带来很多烦人的事情。最后找到源码,在Freemarker源码的Configurable类的isClassicCompatible方法上找到了详细的注释,这里翻译下,不过本人英语比较差,可能会有错误,如果有人不确定可以去看源码。

       原注释大意如下:

       该方法返回Freemarker模板解析引擎是否工作在“Classic Compatibile”模式下。如果这个模式被激活,则Freemarker模板解析引擎将以以下的方式工作:(类似于1.7.x这个版本的运行方式,这个也是1.7.x的版本被称为“经典的Freemarker”的由来)。(译者注:以下的1、2、3、4、5、6是译者自己加的,方便读者看)

       处理未定义的表达式,也就是说"expr"为null值。

       1、作为像表达式“<assign varname=expr>”、“${expr}”、“ otherexpr == expr“、“otherexpr != expr”条件表达式或者是“hash[expr]”表达式的参数,这个参数将被当成空字符来对待。(译者注:这里注意空字符和null是不一样的).

       2、作为“<list expr as item>”、“<foreach item in expr>”这样的表达式的参数,其循环体将不会被执行,和list的长度为0是一样的。

       3、作为“<if>”或者其他布尔表达式命令的参数,空值将被当成是false来处理。非布尔数据模型或者逻辑操作数也可以放在“<if>”表达式中,空模型(长度为零的字符串,空的数组或者hash集合)都被当成是false来对待,其他情况下都被当成是true来处理。

       4、当布尔值被当成字符串(比如用${...}输出,或者是和其他字符串连接),true值将被转换成“true”字符串处理,false值将被转换成空字符串。

       5、提供给<list>和<foreach>的标量数据模型参数将被当成只包含一个该模型的list来处理。(译者注:就是说,传给<list>和<foreach>的参数不是list或者数组类型的,而是单个元素,则会被当成只有一个元素的list或者数组)

       6、“<include>”标签的路径参数将被作为绝对路径处理。(译者注:这里很多网上的文档都没有提过,是本人经过观察发现的,然后从源码和其注释中找到的。在这种情况下,如果传入的ftl路径是相对路径,则会报找不到文件的异常)。

       在其他方面,甚至是在兼容模式下,这个Freemaker解析引擎是2.1引擎,你不会因此而丢掉其他新的功能。

 

      以上就是译文, 那么如果我们设置了全局的classic_compatible属性,而在某个页面上又不想遵守这个属性该怎么办呢?这样就可以在当前这个页面上采用以下的办法,让当前的页面不再支持传统模式:<#setting classic_compatible=false>

本文转载自:http://www.cnblogs.com/Weagle/p/5417947.html

共有 人打赏支持
宇宙星星
粉丝 16
博文 15
码字总数 1753
作品 0
兰州
程序员
freemarker空值的多种处理方法

默认情况下,freemarker的变量必须有值,如果没有被赋值的变量在页面上使用就会抛出异常,出错的信息都会显示在页面上。 解决办法: 方法一、我们可以在页面上使用freemarker变量时 以 ${xx...

taote
2012/03/02
0
0
FreeMarker 快速入门

什么是 FreeMarker? FreeMarker 是一款模板引擎:一种基于模板的、用来生成输出文本(任何来自于 HTML格式的文本用来 自动生成源代码)的通用工具。它是为 Java 程序员提供的一个开发包或者说...

点点与麦兜
2016/03/16
0
0
freemarker语法介绍及其入门

FreeMarker标签使用 一、FreeMarker模板文件主要有4个部分组成 1、文本,直接输出的部分 2、注释,即<#--...-->格式不会输出 3、插值(Interpolation):即${..}或者#{..}格式的部分,将使用数...

wersdffg
2014/09/30
0
0
细数FreeMarker的优缺点

一、 FreeMarker简介 FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。 所谓模板,就是一份已经写好了基本内容,有着固定格式的文档,其中空出或者用占位符标识的内容...

oecp
2011/04/22
0
3
Freemarker中访问Struts2的select标签的问题以及解决办法

用Struts2做MVC,Freemarker做表现层。因为Freemarker中可以访问Struts2的一些标签,在加上Freemarker本身的一些功能,个人觉得这种组合很是方便。 但是这里碰到一个问题:我参考Struts2的标...

yonge
2009/04/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一步步编写自己的PHP爬取代理IP项目(二)

这一章节我们正式开展我们的爬虫项目,首先我们先要知道哪个网站能获取到免费代理IP,目前比较火的有西刺代理,快代理等,这里我们拿西刺代理作为例子。 这里就是一个个免费的IP地址以及各自...

NateHuang
25分钟前
1
0
11-利用思维导图梳理JavaSE-Java的反射机制

11-利用思维导图梳理JavaSE-Java的反射机制 主要内容 1.反射与Class类 1.1.反射概念 1.2.Class类 1.3.实例化Class类 1.4.反射的作用 1.5.Class对象的作用 2.反射的深入应用 2.1.调用无参的成...

飞鱼说编程
31分钟前
1
0
How to serve the world from home computer?

最近在开发web应用,很想知道,通过公网来访问,效果会不会好。今天在做家务的时候,突然想到,如果我自己写一个ip转发的工具,不就可以实现了吗?但是转过头一想,这么大众的想法,怎么会没...

pearma
47分钟前
1
0
今天在码云遇到一个很有意思的人 for Per.js

今天在码云遇到一个很有意思的人,他在我的Per.js项目下面评论了一句,大意为“你试试这句代码,看看速度到底是你快还是Vue快”【当然,这个评论被我手残不小心删掉了...】。 然后我就试了,...

Skyogo
今天
50
0
Java -------- 首字母相关排序总结

Java 字符串数组首字母排序 字符串数组按首字母排序:(区分大小写) String[] strings = new String[]{"ba","aa","CC","Ba","DD","ee","dd"}; Arrays.sort(strings); for (int i ...

切切歆语
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部