<#if>< /#if>标签
事情的起因
最近的大作业里面,考虑到基金产品有两个属性——日增长率和日增长值,因为他们是有正负分的,所以就想着写个判断,大于零就红色,小于零就绿色:
遇到点麻烦
本来就写个判断就好了,可是好巧不巧entity里面我设置的是两个string类型,如下:
本来也是考虑过要不就把实体再重新设计一下,但是因为表早就生成了,这样一改就会出现数据不对等的问题,所以就想把字符串转成数值试一下:
再次遇到问题
这里其实是因为没考虑数值特点,盲目把字符串转数字报错了:
前端报错信息
FreeMarker template error (DEBUG mode; use RETHROW in production!):
Failed to "?eval" string with this error:
---begin-message--- Syntax error in ?eval-ed string in line 1, column 8: Encountered ")",
but was expecting one of: "false" "true" "." "+" "-" "!" "[" "(" "{"
---end-message---
The failing expression: ==> goods.day_up?eval [in template "home/goods/detail.ftl" at line 58,
eclipse报错信息
2021-12-12 16:59:50.598 ERROR 11696 --- [nio-8081-exec-6] freemarker.runtime : Error executing FreeMarker template
freemarker.core._MiscTemplateException: Failed to "?eval" string with this error:
---begin-message---
Syntax error in ?eval-ed string in line 1, column 8:
Encountered ")", but was expecting one of:
<STRING_LITERAL>
<RAW_STRING>
"false"
"true"
<INTEGER>
<DECIMAL>
"."
"+"
"-"
"!"
"["
"("
"{"
<ID>
---end-message---
The failing expression:
==> goods.day_up?eval [in template "home/goods/detail.ftl" at line 58, column 38]
----
FTL stack trace ("~" means nesting-related):
- Failed at: #if goods.day_up?eval lt 0 [in template "home/goods/detail.ftl" at line 58, column 33]
----
at freemarker.core.BuiltInsForStringsMisc$evalBI.calculateResult(BuiltInsForStringsMisc.java:95) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.BuiltInsForStringsMisc$evalBI.calculateResult(BuiltInsForStringsMisc.java:61) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.OutputFormatBoundBuiltIn._eval(OutputFormatBoundBuiltIn.java:42) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.Expression.eval(Expression.java:83) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.EvalUtil.compare(EvalUtil.java:113) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.ComparisonExpression.evalToBoolean(ComparisonExpression.java:62) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.IfBlock.accept(IfBlock.java:49) ~[freemarker-2.3.28.jar:2.3.28]
at freemarker.core.Environment.visit(Environment.java:330) [freemarker-2.3.28.jar:2.3.28]
at freemarker.core.Environment.visit(Environment.java:336) [freemarker-2.3.28.jar:2.3.28]
at freemarker.core.Environment.process(Environment.java:309) [freemarker-2.3.28.jar:2.3.28]
at freemarker.template.Template.process(Template.java:384) [freemarker-2.3.28.jar:2.3.28]
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:389) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:302) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:253) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:178) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875) [spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.12.jar:9.0.12]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.12.jar:9.0.12]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.12.jar:9.0.12]
at java.lang.Thread.run(Thread.java:744) [na:1.8.0]
detail.ftl文件
<li class="ershou-place">
<div class="name">
<span>日增长率</span>
</div>
<div class="value">
<#if goods.day_up?substring(0,1) =='-' >
<span class="real-time" id="creat_time">
<font style="color:green">${goods.day_up}</font>
</span>
<#else>
<span class="real-time" id="creat_time">
<font style="color:red">${goods.day_up}</font>
</span>
</#if>
</div>
</li>
<li class="ershou-place">
<div class="name">
<span>日增长值</span>
</div>
<div class="value">
<#if goods.day_upnum?eval lt 0 >
<span class="real-time" id="creat_time">
<font style="color:green">${goods.day_upnum}</font>
</span>
<#else>
<span class="real-time" id="creat_time">
<font style="color:red">${goods.day_upnum}</font>
</span>
</#if>
</div>
</li>
如上,因为goods.day_up是带百分号的,所以就取了第一个字符,如果发现是负号就设成绿色;goods.day_upnum本身就是数字,所以就先转成了数字。
前端的效果
后来的思考
其实这里还有个bug,要是做测试的话肯定会暴露出来,在发布基金产品写产品信息的时候,是让用户自己输入的,也就是说,如果有人恶意输入别的字符会出现问题的,所以这里必须要设置一个弹窗,如果发现不是数值就要提醒,这也是比较重要的,要改。