[英]How to add the ID of an object to a hidden input of a form with Thymeleaf
I am listing restaurants into a HTML table using th:each. 我正在使用th:each将餐厅列出到HTML表中。 I would like to add a button to every row where I can delete the actual row data (so i want to send the Restaurant ID to Spring, then I would like to delete that restaurant from database. And in each row I also would like to create an Add admin form (because I don't want to create a new HTML page for this only with 1 input field). So basically my question, how can I do this? 我想在每行上添加一个按钮,以便删除实际的行数据(因此我想将餐厅ID发送给Spring,然后从数据库中删除该餐厅。在每一行中,我也想删除创建一个Add admin表单(因为我不想仅使用1个输入字段为此创建一个新的HTML页面。)因此,基本上我的问题是,我该怎么做?
Here is my HTML table: 这是我的HTML表格:
<table class="table">
<thead>
<tr>
<th scope="col">Restaurant</th>
<th scope="col">Delivery time</th>
<th scope="col">Delivery Price</th>
<th scope="col">Minimum Order Price</th>
<th scope="col">Shopping Hours</th>
</tr>
</thead>
<tbody>
<tr th:each="rest: ${restaurants}">
<td th:text="${rest.name}"/>
<td th:text="${rest.avgdeliverytime}"/>
<td th:text="${rest.deliveryprice}"/>
<td th:text="${rest.minorderprice}"/>
<td th:text="${rest.hours.open} + ' - '+ ${rest.hours.close}"/>
<td>
<form th:action="@{'restaurants/delete'}" method="post">
<button type="submit" class="btn btn-danger btn-block"/>
Delete</button>
</form>
</td>
<td>
<form th:action="@{'restaurants/newadmin'}" th:object="${restadmin}" method="post">
<input type="hidden" name="restaurantId" th:value="${rest.id}" th:field="${restadmin.restid}">
<input type="email" class="form-control" id="adminEmail" th:field="${restadmin.email}">
<button type="submit" class="btn btn-secondary btn-block"/>
Add Admin</button>
</form>
</td>
</tr>
</tbody>
</table>
For this, I created a new class, called RestaurantAdmin, to post this object back to Controller 为此,我创建了一个名为RestaurantAdmin的新类,将该对象发回到Controller
public class RestaurantAdmin {
private String email;
private Long restid;
public RestaurantAdmin() {
}
public RestaurantAdmin(String email, Long restid) {
this.email = email;
this.restid = restid;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getRestid() {
return restid;
}
public void setRestid(Long restid) {
this.restid = restid;
}
My Controller methods: 我的控制器方法:
@GetMapping("/restaurants")
public String getAllRestaurants(Model model) {
model.addAttribute("restaurants", restaurantService.findAll());
model.addAttribute("restadmin", new RestaurantAdmin());
return "administration/restaurants";
}
@PostMapping("/restaurants/newadmin")
public ModelAndView addNewAdminToRestaurant(@ModelAttribute(value="restadmin") RestaurantAdmin restaurantAdmin,
final BindingResult result, ModelAndView modelAndView) {
if(result.hasErrors()) {
modelAndView.addObject("error", "Some error are occured!");
modelAndView.setViewName("administration/restaurants");
return modelAndView;
}
System.out.println(restaurantAdmin.getRestid());
System.out.println(restaurantAdmin.getEmail());
modelAndView.setViewName("administration/restaurants");
return modelAndView;
}
With these codes, I don't get any exception, but when I add an email address to Add admin form then post it to Spring, the restaurantAdmin's ID is null. 使用这些代码,我没有任何异常,但是当我向“添加管理表单”添加电子邮件地址并将其发布到Spring时,restaurantAdmin的ID为null。
If I add the following line to the deletion form (which actually makes no sense, because I don't even have object to post or something. ) 如果我将以下行添加到删除表单中(这实际上没有任何意义,因为我什至没有张贴对象或其他东西。)
<input type="hidden" name="restaurantId" th:field="${rest.id}">
I get this exception: 我得到这个例外:
2018-11-09 15:44:16.504 ERROR 17052 --- [nio-8443-exec-3] org.thymeleaf.TemplateEngine : [THYMELEAF][https-jsse-nio-8443-exec-3] Exception processing template "administration/restaurants": An error happened during template parsing (template: "class path resource [templates/administration/restaurants.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/administration/restaurants.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) [thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) [thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:354) [thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:187) [thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.34.jar:8.5.34]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135) [na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.34.jar:8.5.34]
at java.base/java.lang.Thread.run(Thread.java:844) [na:na]
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "administration/restaurants" - line 54, col 82)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parse(MarkupParser.java:257) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
... 87 common frames omitted
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "administration/restaurants" - line 54, col 82)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.Model.process(Model.java:282) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.Model.process(Model.java:290) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.IteratedGatheringModelProcessable.processIterationModel(IteratedGatheringModelProcessable.java:367) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.IteratedGatheringModelProcessable.process(IteratedGatheringModelProcessable.java:221) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement(ProcessorTemplateHandler.java:1640) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleCloseElementEnd(TemplateHandlerAdapterMarkupHandler.java:388) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleCloseElementEnd(InlinedOutputExpressionMarkupHandler.java:322) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleCloseElementEnd(OutputExpressionInlinePreProcessorHandler.java:220) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleCloseElementEnd(InlinedOutputExpressionMarkupHandler.java:164) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.attoparser.HtmlElement.handleCloseElementEnd(HtmlElement.java:169) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.HtmlMarkupHandler.handleCloseElementEnd(HtmlMarkupHandler.java:412) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupEventProcessorHandler.handleCloseElementEnd(MarkupEventProcessorHandler.java:473) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.ParsingElementMarkupUtil.parseCloseElement(ParsingElementMarkupUtil.java:201) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:725) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
... 89 common frames omitted
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'rest' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:305) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:257) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:226) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
... 108 common frames omitted
Edit: Restaurant Entity 编辑:餐厅实体
@Entity
public class Restaurant {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name="RESTAURANT_NAME")
private String name;
@Column(name="AVERAGE_DELIVERY_TIME")
private String avgdeliverytime;
@Column(name="MINIMUM_ORDER_PRICE")
private Short minorderprice;
@Column(name="DELIVERY_PRICE")
private Short deliveryprice;
@Embedded
private ShoppingHours hours;
@ElementCollection
@CollectionTable(name = "MENU", joinColumns = @JoinColumn(name = "RESTAURANT_ID"))
@Column(name = "MENU")
private List<Meal> menu;
@OneToMany
@JoinTable(name = "RESTAURANT_WORKERS",
joinColumns = {@JoinColumn(name = "RESTAURANT_ID")},
inverseJoinColumns = {@JoinColumn(name = "WORKER_ID")})
@Column(name = "WORKER_ID")
private List<User> workers;
public Restaurant() {
}
public Restaurant(String name, String avgdeliverytime, Short minorderprice, Short deliveryprice,
ShoppingHours hours) {
this.name = name;
this.avgdeliverytime = avgdeliverytime;
this.minorderprice = minorderprice;
this.deliveryprice = deliveryprice;
this.hours = hours;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAvgdeliverytime() {
return avgdeliverytime;
}
public void setAvgdeliverytime(String avgdeliverytime) {
this.avgdeliverytime = avgdeliverytime;
}
public Short getMinorderprice() {
return minorderprice;
}
public void setMinorderprice(Short minorderprice) {
this.minorderprice = minorderprice;
}
public Short getDeliveryprice() {
return deliveryprice;
}
public void setDeliveryprice(Short deliveryprice) {
this.deliveryprice = deliveryprice;
}
public ShoppingHours getHours() {
return hours;
}
public void setHours(ShoppingHours hours) {
this.hours = hours;
}
public List<Meal> getMenu() {
return menu;
}
public void setMenu(List<Meal> menu) {
this.menu = menu;
}
} }
You can't add th:value
and th:field
together, because th:field
will override it. 您不能将th:value
和th:field
一起添加,因为th:field
会覆盖它。 What you can do, is remove the th:field
tag and instead use a name and a value. 您可以做的是删除th:field
标记,而是使用一个名称和一个值。 So instead of receiving a @ModelAttribute
, you will be receiving two @RequestParam
. 因此,您将收到两个@RequestParam
,而不是接收@ModelAttribute
。 To do so, you would need to add the following changes to your code. 为此,您需要在代码中添加以下更改。
Controller 控制者
@PostMapping("/restaurants/newadmin")
public ModelAndView addNewAdminToRestaurant(ModelAndView modelAndView,
@RequestParam("restaurantId") Long id,
@RequestParam("email") String email) { ... }
HTML 的HTML
<form th:action="@{'restaurants/newadmin'}" method="post">
<input type="hidden" name="restaurantId" th:value="${rest.id}">
<input type="email" name="email" class="form-control" id="adminEmail">
<button type="submit" class="btn btn-secondary btn-block"/>Add Admin</button>
</form>
Tip 小费
When using th:object
with multiple forms, instead of sending just one RestaurantAdmin
object, you should try to create a new one for each iteration. 当使用具有多种形式的th:object
时,您应该尝试为每次迭代创建一个新的对象,而不是仅发送一个RestaurantAdmin
对象。 A simple way to do this, is adding a @MadelAttribute
to your controller, that will return a new object every time you call it in a th:object
. 一种简单的方法是在控制器中添加一个@MadelAttribute
,每次在th:object
调用它时都会返回一个新th:object
。 Of course, for your case, this won't change anything, since the real solution is receiving two params instead of an object, but is just a small tip. 当然,对于您的情况,这不会有任何改变,因为真正的解决方案是接收两个参数而不是对象,但这只是一个小技巧。
// In order to use th:object in multiple forms, we must be able to map a new entity to that form.
@ModelAttribute(value = "newRestAdmin")
public RestaurantAdmin newRestAdmin() {return new RestaurantAdmin();}
Then on your forms you just fetch the new entity with the given value. 然后在表单上,您只需获取具有给定值的新实体。
<form th:action="@{'restaurants/newadmin'}" th:object="${newRestAdmin}" method="post">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.