【问题标题】:Accessing fields in Thymeleaf with custom Getters/Setters使用自定义 Getter/Setter 访问 Thymeleaf 中的字段
【发布时间】:2019-12-17 14:13:07
【问题描述】:

我正在尝试在我的 Thymeleaf 模板中使用实体,Order 的实例。 Order 有一些可以为空的字段,即CustomerOrderReference。为了显式处理可空性,该字段的 getter 返回 Optional<CustomerOrderReference>(正在使用值对象),然而 setter 采用可空的 CustomerOrderReference

public class Order {
    [...]
    private CustomerOrderReference customerOrderReference;
    [...]

        public Optional<CustomerOrderReference> getCustomerOrderReference() {

        return Optional.ofNullable(customerOrderReference);
    }


    public void setCustomerOrderReference(CustomerOrderReference customerOrderReference) {

        this.customerOrderReference = customerOrderReference;
    }

我在百里香模板中绑定Order

                        <div class="form-group" >
                            <label th:text="#{order-creation.customer-order-reference}"
                                   class="col-xs-12 col-sm-4 control-label"></label>
                            <div class="col-xs-12 col-sm-8">
                                <input th:field="*{customerOrderReference}" th:value="*{customerOrderReference}" class="form-control"
                                       data-test-id="customer-order-reference" id="customer-order-reference"/>
                            </div>
                        </div>

我正在使用自定义解析器/打印机来处理来回发送的值:

public class CustomerOrderReferenceFormatter implements Parser<CustomerOrderReference>,
    Printer<Optional<CustomerOrderReference>> {

    @Override
    public CustomerOrderReference parse(String text, Locale locale) {

        return CustomerOrderReference.from(text).orElse(null);
    }


    @Override
    public String print(Optional<CustomerOrderReference> object, Locale locale) {

        if (object.isPresent()) {
            return object.get().getValue();
        }

        return "";
    }
}

这样做会导致模板解析错误:

java.lang.IllegalArgumentException: Source to convert from must be an instance of [net.xxx.order.model.order.CustomerOrderReference]; instead it was a [java.util.Optional]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:187) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.validation.AbstractPropertyBindingResult.formatFieldValue(AbstractPropertyBindingResult.java:130) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:229) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:129) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:904) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
    at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
    at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
    at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
    at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
[...]

我知道错误的含义——但我不确定错误是如何发生的: 据我所知,注册的自定义格式化程序将用于处理类型(如Optional&lt;CustomerOrderReference&gt;。但情况并非如此。

Thymeleaf/Spring MVC 是否查看字段类型 (CustomerOrderReference) 并因此无法处理 Optional&lt;CustomerOrderReference&gt; 返回类型?

我怎样才能改变这种行为(使用不同的 getter 和 setter/fields 返回类型)?

【问题讨论】:

    标签: java spring-boot thymeleaf


    【解决方案1】:

    您将数据放在Optional 容器中的问题。这是一个特殊的容器类,用于保存可能为空的值,并受到NullPointerException 的保护。

    默认情况下,Thymeleaf 无法处理此类值。我相信您根本不应该在 Thymeleaf 模板中使用的 DTO 对象的 getter 中使用 Optional

    尝试在创建这些 DTO 对象之前或在带有 elvise 运算符 ${somparent?.somechild} 的模板内处理 null 值。

    【讨论】:

    • 很高兴您能提供帮助,但您能重新阅读这个问题吗? 1. 我正在尝试使用 Formatter 处理 Optional 值 2. 我特别询问了如何更改 thymeleaf 默认行为(我想在这里使用 Optional) 3. 我不在这里使用 DTO。
    • 我不认为你可以改变这种行为。至少我从未听说过 Thymeleaf 中的此类功能。
    • 据我所知,这主要是影响 thymeleaf 行为的 Spring MVC 代码......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 2017-10-31
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多