我用thymeleaf视图构建了一个Spring MVC应用程序,遇到了以下问题。我有一个页面,它应该处理一个表单并创建一个新的Entity以持久化在数据库中。在我的控制器类中,我有两个方法来实现这一点。首先,@GetMapping来渲染页面:
@GetMapping("/dispo/orderCreate")
private String showCreateOrder(Model model) {
List<MdUser> userList = service.getUsers();
model.addAttribute("userList", userList);
return "/dispo/orderCreate";
}
我只想显示页面而不向表单添加一些操作,一切都很好。模型属性“userList”正确地填充了数据库中的用户。
现在我修改了视图,在表单中添加了一个动作和一个对象。视图的代码现在看起来像这样:
<form action="#" class="form" id="newOrderForm" th:action="@{/dispo/addOrder}" th:object="${loadOrder}" method="post">
<table class="cont-table" cellpadding="2" cellspacing="2" width="100%">
<tbody>
<tr align="left">
<th align="left" valign="top" width="110">Protokollführer:</th>
<td>
<table border="0" cellpadding="0" cellspacing="1" width="100%">
<tbody>
<tr>
<td height="30">
<select class="selectOneMenue" id="newOrderPersoDropDown" th:field="*{supervisor}">
<option>Bitte auswählen</option>
<option th:each="user : ${userList}"
th:value="user.userId"
th:text="${user.firstName}+' '+${user.lastName}"></option>
</select>
</td>
. . .
</tr>
</tbody>
</table>
<br />
<input style="width:200px" type="submit" value="Speichern" class="commandExButton" id="newOrderSubmit" />
<input style="width:120px" type="reset" value="Zurücksetzen" class="commandExButton" id="newOrderReset" />
</form>
对应的@PostMapping看起来像这样:
@PostMapping("/dispo/addOrder")
public String submit(@ModelAttribute("loadOrder") LoadOrderModel loadOrder, BindingResult result, Model model) {
if (result.hasErrors()) {
return "error";
}
service.createAndSaveLoadOrder(loadOrder);
return "/dispo/success";
}
现在,当使用以下stacktrace到达表单时,视图的呈现会崩溃:
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringActionTagProcessor' (template: "/dispo/orderCreate" - line 41, col 58)
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.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710) ~[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]
... 87 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3030) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.Request.getSession(Request.java:2468) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:896) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:908) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.saveToken(HttpSessionCsrfTokenRepository.java:63) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.saveTokenIfNecessary(LazyCsrfTokenRepository.java:175) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.getToken(LazyCsrfTokenRepository.java:127) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor.getExtraHiddenFields(CsrfRequestDataValueProcessor.java:71) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestDataValueProcessor.getExtraHiddenFields(SpringWebMvcThymeleafRequestDataValueProcessor.java:80) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.requestdata.RequestDataValueProcessorUtils.getExtraHiddenFields(RequestDataValueProcessorUtils.java:79) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.processor.SpringActionTagProcessor.doProcess(SpringActionTagProcessor.java:118) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:142) ~[thymeleaf-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]
... 100 common frames omitted
第41行 TemplateProcessingException 是带有表单标签的那一行。我几乎没有前端开发的经验,所以请耐心等待。我想我必须在这里做一些http会话管理,但不知道该做什么和如何做。有人能帮助我吗?
6条答案
按热度按时间q3qa4bjr1#
我终于成功了。问题确实出在http会话上,或者更准确地说,出在HttpSecurity上。所以我在SecurityConfig类的configure方法中添加了以下内容:
我仍然需要弄清楚SessionCreationPolicy.ALWAYS对我的应用程序的其余部分意味着什么,但现在它工作正常:D。
wvt8vs2t2#
我也有同样的问题;应用了@Raistlin的建议,现在它工作得很好!!
我有一个模态对话框与“form-post”在装货页.它会失败,如果我尝试模态第一.和工程罚款,如果我尝试一个GET页第一,并返回到这个页面;肯定和治疗有关
*always-如果会话不存在,则将始终创建会话
*ifRequired-仅在需要时创建会话(默认)
*never-框架本身不会创建会话,但如果会话已经存在,则会使用会话
*stateless-Spring Security不会创建或使用任何会话
https://www.baeldung.com/spring-security-session
kuarbcqp3#
您需要为表单对象创建新示例
inkz8wg94#
为了在表单中使用
th:object
,我们必须能够将新实体Map到该表单。您可以通过属性发送它,或者您可以在控制器中设置类似下面的方法,它会自动为您完成。wpcxdonn5#
我在从Sping Boot 1.x升级到2.x时遇到了同样的问题(其中还包括较新的Thymeleaf版本)。我的问题是Thymeleaf试图为每个html表单自动创建隐藏的csrf输入。生成的csrf令牌需要持久化在http会话中。
启用会话(如@Raistlin所示)或禁用csrf保护(
http.csrf().disable()
)为我解决了这个问题。您还可以使用
http.csrf().requireCsrfProtectionMatcher(..)
或http.csrf().ignoringRequestMatchers(..)
将csrf令牌限制到某些页面1hdlvixo6#
此错误的主要原因是Thymeleaf在生成时会立即输出内容。当处理器到达表单时,Spring Security突然启动并希望生成新的会话(将CSRF令牌注入表单)。
解决方案是缓冲thymeleaf输出-讨论可在这里https://github.com/thymeleaf/thymeleaf-spring/issues/113
在应用程序属性中
然后您仍然可以使用会话ifRequired。