当我在 Thymeleaf 的表单标签中一起使用 th:action 和 method 属性时,它给了我异常

问题描述 投票:0回答:3

这很奇怪,当我在表单标签中使用 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"后没有异常

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

请查看下面所附的代码

  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.


java spring-boot thymeleaf
3个回答
1
投票

SO 上有多个问题解释了类似的问题,但除了这个答案之外,大多数问题都没有答案这里

我进一步检查了我的情况,每次未手动设置或修改 JSESSIONID 时,都会出现此错误。

我做了一些小实验来弄清楚在哪种情况下问题会消失:

  1. 使用会话创建策略始终可以通过始终生成会话来解决问题。
    .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
  1. 使用csrf令牌存储库(如Spring安全问题3906中所述)还有助于通过急切地创建csrf令牌来持久化它(不使用惰性持久性)。也可以使用 CookieCsrfTokenRepository
    .csrf()
        .csrfTokenRepository(new HttpSessionCsrfTokenRepository())

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


0
投票

错误说org.thymeleaf.exceptions.TemplateInputException:模板解析期间发生错误(模板:“类路径资源[templates //view/checkout.html]”)

注意视图之前的双//。尝试在返回语句中的视图之前删除 /


0
投票

根据@sbsatter的回答,我设法解决了我的问题。由于一些

depricated
标志,我不得不稍微修改一下代码。对于 Spring Boot 3.x,它看起来更像是:

 http.authorizeHttpRequests(
      requests -> requests.anyRequest().permitAll())
      .sessionManagement(sm ->  
          sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
      )
      .csrf(csrf ->
          csrf.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
      );
© www.soinside.com 2019 - 2024. All rights reserved.