Spring Boot 当我在Thymeleaf中的form标签中同时使用th:action和method属性时,它会给我异常

vkc1a9a2  于 6个月前  发布在  Spring
关注(0)|答案(3)|浏览(73)

这是非常奇怪的,当我在表单标签中的第: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”后无异常

我不明白它为什么会这样。

请查看下面随附的代码

  1. Html代码
<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>


1.模型

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;
    }
}


1.控制器

@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.

pobjuy32

pobjuy321#

SO上有多个问题解释了类似的问题,但除了这个答案here外,大多数问题都没有答案。
我在我的案例中进一步检查了这个问题,每次JSESSIONID没有手动设置或修改时,都会出现这个错误。
我做了一些小实验来弄清楚在什么情况下这个问题会消失:
1.使用会话创建策略ALWAYS可以通过始终生成会话来解决问题。

.and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)

字符串
1.使用csrf token repository(如Spring Security Issue 3906中所述)也有助于通过急切地创建csrf token来持久化csrf token(而不使用惰性持久化)。也可以使用CookieCsrfTokenRepository

.csrf()
        .csrfTokenRepository(new HttpSessionCsrfTokenRepository())


对于匿名用户,应用程序仅在需要时生成会话,因此,在呈现表单时请求CSRF令牌可能会在某些情况下导致此问题,例如在长html文件中延迟呈现表单。

az31mfrm

az31mfrm2#

Error says org.thymeleaf.exceptions.TemplateInputException:模板解析过程中出错(template:“class path resource [templates//view/checkout.html]”)
注意双重// before视图。尝试在return语句中删除/ before视图

d6kp6zgx

d6kp6zgx3#

基于@sbsatter的回答,我设法解决了我的问题。由于一些depricated标志,我不得不修改代码。对于Sping Boot 3.x,它看起来更像:

http.authorizeHttpRequests(
      requests -> requests.anyRequest().permitAll())
      .sessionManagement(sm ->  
          sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
      )
      .csrf(csrf ->
          csrf.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
      );

字符串

相关问题