这很奇怪,当我在表单标签中使用 th:action 和 method 属性时,它给了我异常,但是当我从表单标签中删除 method 属性时,没有发生异常。我的意思是 什么时候用
<form id="deliveryAddressForm" action="#" th:action="@{/product/save-address}" method="post" th:object="${address}">
发生异常
<form id="deliveryAddressForm" action="#" th:action="@{/product/save-address}" th:object="${address}">
删除method="post"后没有异常
我不明白为什么它会这样。
请查看下面所附的代码
<form id="deliveryAddressForm" action="#" th:action="@{/product/save-address}" method="post" th:object="${address}">
<!-- Invoice Address-->
<h3 class="mb-4"> Invoice address</h3>
<div class="row">
<div class="form-group col-md-6">
<label class="form-label" for="fullname_invoice">Full Name</label>
<input class="form-control" type="text" th:field="*{name}" placeholder="Joe Black" id="fullname_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="emailaddress_invoice">Email Address</label>
<input class="form-control" type="text" th:field="*{email}" placeholder="[email protected]" id="emailaddress_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="phonenumber_invoice">Phone Number</label>
<input class="form-control" type="text" th:field="*{mobile}" placeholder="Phone Number" id="phonenumber_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="street_invoice">Street</label>
<input class="form-control" type="text" th:field="*{street}" placeholder="123 Main St." id="street_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="city_invoice">City</label>
<input class="form-control" type="text" th:field="*{city}" placeholder="City" id="city_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="zip_invoice">Pincode</label>
<input class="form-control" type="text" th:field="*{pincode}" placeholder="Postal code" id="zip_invoice">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="state_invoice">Land Mark</label>
<input class="form-control" type="text" th:field="*{landmark}" placeholder="State" id="state_invoice">
</div>
<div class="form-group col-12 mt-3">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="show-shipping-address" type="checkbox" name="clothes-brand">
<label class="custom-control-label align-middle" for="show-shipping-address" data-toggle="collapse" data-target="#shippingAddress">Use a different shipping address</label>
</div>
</div>
</div>
<!-- /Invoice Address-->
<!-- Shippping Address-->
<div class="collapse" id="shippingAddress">
<h3 class="my-4">Shipping address </h3>
<div class="row">
<div class="form-group col-md-6">
<label class="form-label" for="street_shipping">Street</label>
<input class="form-control" type="text" th:field="*{street1}" placeholder="123 Main St." id="street_shipping">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="city_shipping">City</label>
<input class="form-control" type="text" th:field="*{city1}" placeholder="City" id="city_shipping">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="zip_shipping">Pin</label>
<input class="form-control" type="text" th:field="*{pincode1}" placeholder="Postal code" id="zip_shipping">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="state_shipping">Land Mark</label>
<input class="form-control" type="text" th:field="*{landmark1}" placeholder="State" id="state_shipping">
</div>
<div class="form-group col-md-6">
<label class="form-label" for="phonenumber_shipping">Phone Number</label>
<input class="form-control" type="text" th:field="*{mobile1}" placeholder="Phone Number" id="phonenumber_shipping">
</div>
</div>
</div>
<!-- /Shipping Address-->
<div class="my-5 d-flex justify-content-between flex-column flex-lg-row"><a class="btn btn-link text-muted" href="#"> <i class="fa fa-angle-left mr-2"></i>Back </a><a class="btn btn-dark forward-btn" data-pan="1" href="javascript:void(0)" id="saveDeliveryAddressForm">Choose delivery method<i class="fa fa-angle-right ml-2"></i></a></div>
</form>
package com.ij.ikimall.bean;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Component
public class AddressBean implements Serializable {
private String name;
private String email;
private String mobile;
private String street;
private String city;
private String pincode;
private String landmark;
private String mobile1;
private String street1;
private String city1;
private String pincode1;
private String landmark1;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
public String getLandmark() {
return landmark;
}
public void setLandmark(String landmark) {
this.landmark = landmark;
}
public String getMobile1() {
return mobile1;
}
public void setMobile1(String mobile1) {
this.mobile1 = mobile1;
}
public String getStreet1() {
return street1;
}
public void setStreet1(String street1) {
this.street1 = street1;
}
public String getCity1() {
return city1;
}
public void setCity1(String city1) {
this.city1 = city1;
}
public String getPincode1() {
return pincode1;
}
public void setPincode1(String pincode1) {
this.pincode1 = pincode1;
}
public String getLandmark1() {
return landmark1;
}
public void setLandmark1(String landmark1) {
this.landmark1 = landmark1;
}
}
@GetMapping("/checkout/{productEncId}")
public String checkout(@PathVariable(value = "productEncId")String productEncId,Model model) {
Product product = productService.findByEncryptedId(productEncId);
model.addAttribute("productEncId",productEncId);
AddressBean address = new AddressBean();
model.addAttribute("address",address);
return "view/checkout";
}
另请查看生成的详细异常情况
2020-08-28 15:51:08.507 ERROR 20228 --- [nio-8989-exec-8] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8989-exec-8] Exception processing template "view/checkout": An error happened during template parsing (template: "class path resource [templates/view/checkout.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/view/checkout.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringActionTagProcessor' (template: "view/checkout" - line 41, col 79)
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]
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringActionTagProcessor' (template: "view/checkout" - line 41, col 79)
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]
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2999) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.connector.Request.getSession(Request.java:2441) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
2020-08-28 15:51:08.524 ERROR 20228 --- [nio-8989-exec-8] 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.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/view/checkout.html]")] with root cause
java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2999) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
2020-08-28 15:51:08.640 ERROR 20228 --- [nio-8989-exec-8] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/product/checkout/fvssrg5OLcM=] and exception [An error happened during template parsing (template: "class path resource [templates/view/checkout.html]")] as the response has already been committed. As a result, the response may have the wrong status code.
SO 上有多个问题解释了类似的问题,但除了这个答案之外,大多数问题都没有答案这里。
我进一步检查了我的情况,每次未手动设置或修改 JSESSIONID 时,都会出现此错误。
我做了一些小实验来弄清楚在哪种情况下问题会消失:
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.csrf()
.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
对于匿名用户,应用程序仅在需要时生成会话,因此,在渲染表单时请求 CSRF 令牌可能会在某些情况下导致此问题,例如在长 html 文件中延迟渲染表单。
错误说org.thymeleaf.exceptions.TemplateInputException:模板解析期间发生错误(模板:“类路径资源[templates //view/checkout.html]”)
注意视图之前的双//。尝试在返回语句中的视图之前删除 /
根据@sbsatter的回答,我设法解决了我的问题。由于一些
depricated
标志,我不得不稍微修改一下代码。对于 Spring Boot 3.x,它看起来更像是:
http.authorizeHttpRequests(
requests -> requests.anyRequest().permitAll())
.sessionManagement(sm ->
sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
)
.csrf(csrf ->
csrf.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
);