【问题标题】:Thymeleaf variable out of scope?Thymeleaf 变量超出范围?
【发布时间】:2016-03-05 18:33:11
【问题描述】:

我不确定我在这里做错了什么。带有“th:if”的第一个 div 可以正常访问 ${po} 对象,但带有“th:if”的第二个 div 不能。我不明白。我正在使用 Spring Boot 1.3.0。下面第一行是98,最后一行是147。文件名为“tabs.html”

<li class="" th:each="po : ${session.uso.parties}" th:object="${po}"><a href="#"
                    th:text="*{getSimpleDisplayName()}">Jack</a> <!-- line 98 -->

                    <form class="form-horizontal poForm" role="form" action="#" th:action="@{/updatePersonOrg}" th:object="${po}"
                        method="post">

                        <div th:if="*{isOrg()}">
                            <div class="form-group">
                                <label class="col-xs-4 control-label" for="name">Org Name</label>
                                <div class="col-xs-8">
                                    <input class="form-control" type="text" th:field="*{name}" />
                                </div>
                            </div>
                            <div th:switch="*{isAgencyNotEmployer}" th:remove="tag">

                                <div th:case="${true}" th:remove="tag">
                                    <div class="form-group">
                                        <label class="col-xs-4 control-label" for="agencySystemAccount">System Account</label>
                                        <div class="col-xs-8">
                                            <input class="form-control" type="text" th:field="*{agencySystemAccount}" />
                                        </div>
                                    </div>
                                </div>
                                <div th:case="${false}" th:remove="tag">
                                    <!-- Is employer. -->
                                    <div class="form-group">
                                        <label class="col-xs-4 control-label" for="fedTaxId">Federal Tax ID</label>
                                        <div class="col-xs-8">
                                            <input class="form-control" type="text" placeholder="123-45-6789" th:field="*{fedTaxId}" />
                                        </div>
                                    </div>
                                    <div class="form-group">
                                        <label class="col-xs-4 control-label" for="employee">Employee</label>
                                        <div class="col-xs-8">
                                            <select class="form-control" th:field="*{employee}">

                                                <option th:each="person : ${uso.peopleNotOrgs()}" th:value="${person}" th:text="${person.name}">Jill</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div th:if="*{isPerson()}">
                            <fieldset>
                                <legend>Person Name</legend>
                                <div class="form-group">
                                    <label class="col-xs-4 control-label" for="prefixName">Name Prefix</label>
                                    <div class="col-xs-8">
                                        <input class="form-control" type="text" th:field="*{prefixName}" /><!-- line 147 -->

错误是,“java.lang.IllegalStateException: Bean name 'po' 的 BindingResult 和普通目标对象都不能用作请求属性”在上面代码的第 147 行。

2015-12-01 10:32:23.985 ERROR 5776 --- [nio-8080-exec-3] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-8080-exec-3] Exception processing template "tabs": Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (tabs:147)
2015-12-01 10:32:23.994 ERROR 5776 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (tabs:147)] with root cause

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'po' available as request attribute
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.thymeleaf.spring4.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:396) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:323) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:289) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.spring4.processor.attr.AbstractSpringFieldAttrProcessor.processAttribute(AbstractSpringFieldAttrProcessor.java:98) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1017) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:972) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:695) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:668) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Node.processNode(Node.java:990) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.dom.Document.process(Document.java:93) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1155) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring4-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_66]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_66]

【问题讨论】:

  • 你在对象 po 上有一个 getter isPerson() 吗?
  • 没有。 isPerson() 是对象 "po" 上的公共方法,就像 isOrg() 一样。所以它们不是字段,而是公共方法。
  • 你能把这个类的Java代码也发一下吗?
  • 不幸的是,没有。我的雇主不允许我发布整个文件。该文件只是一个复杂对象图的一部分。它是一个代表个人或组织的抽象类。两个具体类 Person 和 Org 扩展了抽象类。在呈现 tabs.html 时,${po} 对象应该是 Person 或 Org 的一个实例。

标签: java spring spring-boot thymeleaf


【解决方案1】:

在 Twitter 上,Daniel Fernandez [https://twitter.com/danfenz],告诉我 SpringMVC 只支持第一级对象作为表单支持 bean。我正在使用集合中的对象。我需要更改我的控制器以使用单个对象而不是会话中的深层对象图。所以,我会尝试并报告。

【讨论】:

  • 确实,这正是我的问题。谢谢你,丹。
【解决方案2】:

这应该很简单。

问题是您两次使用 ${po} 作为百里香对象,一次在第 98 行上方,一次在表单标记中。

删除表单标签应该可以解决您的问题。

参考:Spring Boot Adding Model to the View with Thymeleaf and MVC

http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#expression-basic-objects

希望这会有所帮助。

【讨论】:

  • 感谢您的建议,但错误仍然存​​在。删除表单标签中的 ${po} 引用后,我重新启动了我的开发服务器。 [可能没有必要,因为我关闭了 thymeleaf 模板缓存。] 现在,错误消息是相同的,仍然指向同一行 147。我昨天尝试了相同的解决方案,但没有运气。还有其他想法吗?提升的调试日志会告诉我更多信息吗?
  • 我猜,它没有采用正确的当前上下文,请尝试使用 ${po.isPerson()} 和 ${po.prefixName} 代替..
  • 我先尝试了 ${po.prefixName} 并且错误消息没有改变。然后我尝试了 ${po.isPerson()} 并将错误消息更改为这个......“异常处理模板“选项卡”:评估 SpringEL 表达式的异常:“po.isPerson()”(tabs:140) 评估 SpringEL 表达式的异常: "po.isPerson()" (tabs:140)] 根本原因是 org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): 在“湖”类型的对象上找不到属性或字段“po”。 childsupport.domain.Person' - 也许不公开?”
  • 是的,异常清除它,当前上下文是从上一个选项标签的 Person 对象中获取的。并且 * 应该只与当前上下文一起使用。我的建议是删除 th :object of ${po} in li 并用 ${po.objects} 替换所有 *{objects} 对象。这将确保上下文..即使您更改选项标签中的值..希望这是有道理的..
  • 嗯,所以如果我进行这些更改,那么当我的表单提交给我的控制器时,我可能会丢失支持 bean?但也许这并不重要,因为我的会话对象将随着用户的更改而更新。我试试看。
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2020-12-24
  • 2013-10-26
  • 2016-01-09
  • 2018-09-19
相关资源
最近更新 更多