freemarker的classic_compatible设置,解决报空错误
前段时间接触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>
freemarker的classic_compatible设置,解决报空错误的更多相关文章
- boke练习: freemarker对空变量报错 (classic_compatible设置true,解决报空错误)
我有一个变量: commentModel 默认只是为空, 在freemarker模板中使用<#if>判断是报错 <#if commentModel> ..... </#i ...
- unity3d由于Camera.main.transform报空引用错误的解决方案
今天在导入character包后,引用了内置的第三人称素材,但是在启动的时候程序报空引用的错误: 引起错误的位置在: 错误原因是因为没有将摄像机的tag设置为maincamera,改为maincame ...
- Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法。
Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法. 在本地计算机无法启动MYSQL服务错误1067进程意外终止.这种情况一般是my.ini文件配置出错了1.首 ...
- LR报-27727错误解决办法
1.报如下错误:Action.c(4):Error-27727:Step download timeout(120 seconds) has expired when downloading reso ...
- MySql报2006error错误的解决方法(数据过大)
最近迁移项目中发现,转移数据库出现的几个问题,其中之一就是 2006 error,解决过程如下: 首先贴出报错结果 [Msg] Finished - Unsuccessfully 出现这个结果,首先检 ...
- 解决IIS部署网站引用woff/woff2/svg字体报404错误
一.问题 在IIS上部署网站,网页引用woff字体时,浏览器报“找不到woff.woff2字体”.“404”错误,不仅预设的字体加载不出来,还影响网页加载速度. 二.原因 IIS默认设置情况下不识别. ...
- Nginx 反向代理报400错误解决方法!
如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败,报400错误,解决办法: ...
- win10安装LoadRunner时,安装.net framwork组件报0x800F081F错误 解决办法
一.报错原因 0x800F081F错误大多数是在安装软件时,系统无法联网自动下载安装. 经过各种排查及搜索解决方案,总结原因无非以下三种: 1.windows update被禁用. 2.电脑没有.ne ...
- 微信小程序访问豆瓣api报403错误解决方法
通过豆瓣API可以获取很多电影.书籍的数据信息,今天在调用豆瓣正在上映电影接口的时候报403错误,原因是豆瓣设置了小程序的访问权限.如下: 解决方法是使用代理,将豆瓣API地址换成 https://d ...
随机推荐
- [Note] 计算机网络的应用层
应用层 原理 结构和模型 客户-服务器体系结构(client-server architecture ) 通信不是直接的,需要通过服务器转发 经常会在服务器积压大量的负载 服务器(server) 服务 ...
- 为什么说DOM操作很慢
转自http://www.cnblogs.com/yuzhongwusan/articles/5275933.html 一直都听说DOM很慢,要尽量少的去操作DOM,于是就想进一步去探究下为什么大 ...
- Linux基础一
基本命令 useradd xxx 创建一个用户 uname 查看系统架构信息 uname -a 显示详细信息 uname -r 显示内核信息 date 显示当前网络时间 cat ...
- Mycat 分布式事务的实现
引言:Mycat已经成为了一个强大的开源分布式数据库中间件产品.面对企业应用的海量数据事务处理,是目前最好的开源解决方案.但是如果想让多台机器中的数据保存一致,比较常规的解决方法是引入"协调 ...
- R语言︱非结构化数据处理神器——rlist包
本文作者:任坤,厦门大学王亚南经济研究院金融硕士生,研究兴趣为计算统计和金融量化交易,pipeR,learnR,rlist等项目的作者. 近年来,非关系型数据逐渐获得了更广泛的关注和使用.下面分别列举 ...
- 《CLR Via C#》学习--线程开销
线程内核对象(thread kernel object) OS为系统中创建的每个线程都分配并初始化这种数据结构之一.在该数据结构中,包含一组对线程进行描述的属性. 数据结构中还包含所谓的线程上下文(t ...
- 改造 vue-cli 脚手架
改造 vue-cli 脚手架 注意,这里使用的 vue-cli 的版本为 2.8.2,不同版本的 vue-cli 可能会有些许不一样. 一.配置多页面 项目开发目录: 需要注意一点,每个页面的文件夹命 ...
- 由会话信息保存认识ThreadLocal
这次想总结ThreadLocal这个东西,也是由于项目中使用到了它去帮助保存会话信息.传统的(或者说我在学校的时候)方法,大多是用服务端的session保存会话,与浏览器端的cookie协作去追踪这个 ...
- RobotFramework下的http接口自动化Get Response Status 关键字的使用
Get Response Status 关键字用来获取http请求返回的http状态码. 示例1:访问苏宁易购网站上的http推荐接口,使用Get Response Status 关键字来获取返回的h ...
- 求小于n的素数个数
本文是对 LeetCode Count Primes 解法的探讨. 题目: Count the number of prime numbers less than a non-negative num ...