Correct way to use a th:with Thymeleaf local variable within a form

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Correct way to use a th:with Thymeleaf local variable within a form

balteo
I use form backing objects that all share an abstract base class. One of the properties of this base class is named model but it can represent anything of the entities of my domain model.

Now what I would like to do is use th:with in order to rename the model property to the name of my entities i.e. curriculum, advertisement, etc. thus my different Thymeleaf templates would read nicer with advertisement than with model.

Here is what I have tried:

<form th:object="${advertisementForm}" th:with="advertisement=*{model}" th:action="@{${postUrl}}" method="post" class="form-horizontal">
(model is a property of advertisementForm)

When I then try to access my newly created advertisement variable as follows:

<input type="hidden" th:field="${advertisement.id}"/>

I get a:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'advertisement' available as request attribute

indicating that the local variable is not used.

Note: I have posted a similar thread on SO.
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

Zemi
Administrator
Hello,

do you notice any difference using?
    th:with="advertisement=${advertisementForm.model}"

Regards,
   Zemi

Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

balteo
Hi,
Yes I did try that too. It get the same error message...
Regards,
Julien.
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

balteo
Here is the full stack trace:

2014-11-12 13:00:49.706 ERROR 7489 --- [nio-8080-exec-9] 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' (advertisements/childcare-worker/form:18)] with root cause

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'advertisement' available as request attribute
        at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
        at org.thymeleaf.spring4.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:348)
        at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:293)
        at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:260)
        at org.thymeleaf.spring4.processor.attr.AbstractSpringFieldAttrProcessor.processAttribute(AbstractSpringFieldAttrProcessor.java:97)
        at org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87)
        at org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212)
        at org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1016)
        at org.thymeleaf.dom.Node.processNode(Node.java:971)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(Nesde.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.Document.process(Document.java:93)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1155)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
        at org.thymeleaf.extras.tiles2.renderer.ThymeleafAttributeRenderer.write(ThymeleafAttributeRenderer.java:155)
        at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
        at org.thymeleaf.extras.tiles2.renderer.MetadataCleaningAttributeRendererWrapper.render(MetadataCleaningAttributeRendererWrapper.java:147)
        at org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
        at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
        at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
        at org.apache.tiles.template.InsertAttributeModel.execute(InsertAttributeModel.java:157)
        at org.thymeleaf.extras.tiles2.dialect.processor.AbstractTilesFragmentHandlingAttrProcessor.getModifiedChildren(AbstractTilesFragmentHandlingAttrProcessor.java:169)
        at org.thymeleaf.processor.attr.AbstractChildrenModifierAttrProcessor.processAttribute(AbstractChildrenModifierAttrProcessor.java:58)
        at org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87)
        at org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212)
        at org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1016)
        at org.thymom.Node.processNode(Node.java:971)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.Document.process(Document.java:93)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1155)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
        at org.thymeleaf.extras.tiles2.renderer.ThymeleafAttributeRenderer.write(ThymeleafAttributeRenderer.java:155)
        at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
        at org.thymeleaf.extras.tiles2.renderer.MetadataCleaningAttributeRendererWrapper.render(MetadataCleaningAttributeRendererWrapper.java:147)
        at org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
        at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
        at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
        at org.apache.tiles.template.InsertAttributeModel.execute(InsertAttributeModel.java:157)
        at org.thymeleaf.extras.tiles2.dialect.processor.AbstractTilesFragmentHandlingAttrProcessor.getModifiedChildren(AbstractTilesFragmentHandlingAttrProcessor.java:169)
        at org.thymeleaf.processor.attr.AbstractChildrenModifierAttrProcessor.processAttribute(AbstractChildrenModifierAttrProcessor.java:58)
        at org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87)
        at org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212)
        at org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1016)
        at org.thymeleaf.dom.Node.processNode(Node.java:971)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.NestableNode.computeNextChild(NestableNode.java:672)
        at org.thymeleaf.dom.NestableNode.doAdditionalProcess(NestableNode.java:655)
        at org.thymeleaf.dom.Node.processNode(Node.java:990)
        at org.thymeleaf.dom.Document.process(Document.java:93)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1155)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
        at org.thymeleaf.extras.tiles2.renderer.ThymeleafAttributeRenderer.write(ThymeleafAttributeRenderer.java:155)
        at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
        at org.thymeleaf.extras.tiles2.renderer.MetadataCleaningAttributeRendererWrapper.render(MetadataCleaningAttributeRendererWrapper.java:111)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
        at org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView.render(ThymeleafTilesView.java:125)
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
        at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
        at org.springframework.web.servlet.Framewlet.processRequest(FrameworkServlet.java:966)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:280)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        at org.springframework.security.web.Filteroxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:87)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.clicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:88)
        at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:66)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
        at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
        at org.apache.tomcat.util.net.NioEnSocketProcessor.run(NioEndpoint.java:1523)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

Zemi
Administrator
In reply to this post by balteo
Hello,

looking at source code th:with has a precedence value of 600 and th:object has a precedence value of 500.

You could try to do something like:

    <form th:object="...">
       <div th:with="...">
            <input th:field="..." />
       </div>
    </form>

(Sorry, I cannot try it by myself at this moment).

Regards,
   Zemi

Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

balteo
I have tried as follows:

	
<form th:object="${advertisementForm}"  th:action="@{${postUrl}}" method="post" class="form-horizontal">
   <div th:with="advertisement=${advertisementForm.model}">

and I get the same error as before...

Regards,
Julien.
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

Zemi
Administrator
Sorry, I was looking at the problem from the wrong side.

There is no issue with the th:with just as you wrote it at the first moment (I have just tried it).

The problem is in the line


    <input type="hidden" th:field="${advertisement.id}"/>


th:field only works with *{...} expressions (see http://www.thymeleaf.org/apidocs/thymeleaf-spring4/2.1.3.RELEASE/org/thymeleaf/spring4/processor/attr/AbstractSpringFieldAttrProcessor.html).

With th:field you can only refer to properties of the th:object form bean, so I don't know if there is a way to achieve what you want to do.

Regards,
   Zemi


Reply | Threaded
Open this post in threaded view
|

Re: Correct way to use a th:with Thymeleaf local variable within a form

balteo
Yes. You're right. Thanks a lot for your help anyway!