使用自定义 Getters/Setters 访问 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<CustomerOrderReference>.但事实并非如此。

Thymeleaf/Spring MVC是否查看字段类型(CustomerOrderReference(,因此无法处理Optional<CustomerOrderReference>返回类型?

如何更改此行为(对 getter 和 setter/field 使用不同的返回类型(?

数据位于Optional容器中的问题。一个特殊的容器类来保存值,该值可能为空,并受到NullPointerException的保护。

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

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

最新更新