我怎样才能使 Wicket 7 与 Java 8 中的 java.time 一起工作?
How can I bring Wicket 7 to work with java.time from Java 8?
我有很多bean,都使用LocalDate 和LocalDateTime。 Wicket 中的 DateTextField 和所有其他小部件(如 DatePicker)仅适用于 java.util.Date。有什么方法可以注入一个转换器到 Wicket 7 中,以便它使用 LocalDate 或 LocalDateTime?
豆子长这样:
public class SomeBean {
Long id = null;
LocalDate since = null;
// plus getters and setters
}
Wicket 表单当前使用 CompoundPropertyModel
CompoundPropertyModel<SomeBean> model = new CompundPropertyModel<>( bean );
您可以将 LocalDate
等模型包装在 IModel<java.util.Date>
中,例如
public static class LocalDateModel implements IModel<java.util.Date> {
private IModel<LocalDate> localDateModel;
public LocalDateModel(IModel<LocalDate> localDateModel){
this.localDateModel = localDateModel;
}
@Override
public Date getObject() {
return convertLocalDateToUtilDateSomehow(localDateModel.getObject());
}
@Override
public void setObject(Date object) {
localDateModel.setObject(convertUtilDateToLocalDateSomehow(object));
}
@Override
public void detach() {
localDateModel.detach();
}
}
如果您随后将这样的模型输入到您要使用的表单组件中,它应该可以正常工作。
如果您希望 CompoundPropertyModel
自动提供此类包装模型,您需要扩展它并覆盖它的 CompoundPropertyModel#wrapOnInheritance(Component component)
方法以推断需要包装模型。像
@Override
public <C> IWrapModel<C> wrapOnInheritance(Component component)
{
IWrapModel<C> actualModel = super.wrapOnInheritance(component);
if (actualModel.getObject() instanceOf LocalDate) {
return new LocalDateModelButAlsoWrapping(actualModel);
} else {
return actualModel;
}
}
毫无疑问,LocalDateModelButAlsoWrapping
只是上述 LocalDateModel
示例的扩展,但它也实现了 IWrapModel<T>
。
如果您使用此扩展而不是常规 CompoundPropertyModel
,它将检测字段何时为 LocalDate
并为组件(例如您的 DateTextField
)提供模型,这些组件被包装成看起来像java.util.Date
模型。
虽然我给你的代码片段很脏(你可能不应该让模型对象推断它的类型)因为我提供它只是为了说明一般机制,所以我建议你设计自己的方式来推断预期的对象类型(例如,您可以检查 Component
参数是否为 DateTextField
),但这是我可以想象的解决方案的总体方向。
您可以注册自己的转换器:
https://ci.apache.org/projects/wicket/guide/7.x/guide/forms2.html#forms2_3
@Override
protected IConverterLocator newConverterLocator() {
ConverterLocator defaultLocator = new ConverterLocator();
defaultLocator.set(Pattern.class, new RegExpPatternConverter());
return defaultLocator;
}
您可以简单地从 Wicket 8 向后移植转换器 类。您会发现这些附加到此提交:https://issues.apache.org/jira/browse/WICKET-6200(AbstractJavaTimeConverter 和您需要的任何子类 LocalDate, LocalDateTime、LocalTime 等)
当然,这对 DateTextField 没有帮助,因为它具有硬编码的 Date 类型参数。为此,您可以使用上述转换器创建自己的 sub类,或者使用常规标签和 TextField,并在全局注册转换器,如下所示:
@Override
protected IConverterLocator newConverterLocator() {
ConverterLocator converterLocator = new ConverterLocator();
converterLocator.set(LocalDateTime.class, new LocalDateTimeConverter());
converterLocator.set(LocalDate.class, new LocalDateConverter());
converterLocator.set(LocalTime.class, new LocalDateConverter());
return converterLocator;
}
我有很多bean,都使用LocalDate 和LocalDateTime。 Wicket 中的 DateTextField 和所有其他小部件(如 DatePicker)仅适用于 java.util.Date。有什么方法可以注入一个转换器到 Wicket 7 中,以便它使用 LocalDate 或 LocalDateTime?
豆子长这样:
public class SomeBean {
Long id = null;
LocalDate since = null;
// plus getters and setters
}
Wicket 表单当前使用 CompoundPropertyModel
CompoundPropertyModel<SomeBean> model = new CompundPropertyModel<>( bean );
您可以将 LocalDate
等模型包装在 IModel<java.util.Date>
中,例如
public static class LocalDateModel implements IModel<java.util.Date> {
private IModel<LocalDate> localDateModel;
public LocalDateModel(IModel<LocalDate> localDateModel){
this.localDateModel = localDateModel;
}
@Override
public Date getObject() {
return convertLocalDateToUtilDateSomehow(localDateModel.getObject());
}
@Override
public void setObject(Date object) {
localDateModel.setObject(convertUtilDateToLocalDateSomehow(object));
}
@Override
public void detach() {
localDateModel.detach();
}
}
如果您随后将这样的模型输入到您要使用的表单组件中,它应该可以正常工作。
如果您希望 CompoundPropertyModel
自动提供此类包装模型,您需要扩展它并覆盖它的 CompoundPropertyModel#wrapOnInheritance(Component component)
方法以推断需要包装模型。像
@Override
public <C> IWrapModel<C> wrapOnInheritance(Component component)
{
IWrapModel<C> actualModel = super.wrapOnInheritance(component);
if (actualModel.getObject() instanceOf LocalDate) {
return new LocalDateModelButAlsoWrapping(actualModel);
} else {
return actualModel;
}
}
毫无疑问,LocalDateModelButAlsoWrapping
只是上述 LocalDateModel
示例的扩展,但它也实现了 IWrapModel<T>
。
如果您使用此扩展而不是常规 CompoundPropertyModel
,它将检测字段何时为 LocalDate
并为组件(例如您的 DateTextField
)提供模型,这些组件被包装成看起来像java.util.Date
模型。
虽然我给你的代码片段很脏(你可能不应该让模型对象推断它的类型)因为我提供它只是为了说明一般机制,所以我建议你设计自己的方式来推断预期的对象类型(例如,您可以检查 Component
参数是否为 DateTextField
),但这是我可以想象的解决方案的总体方向。
您可以注册自己的转换器:
https://ci.apache.org/projects/wicket/guide/7.x/guide/forms2.html#forms2_3
@Override
protected IConverterLocator newConverterLocator() {
ConverterLocator defaultLocator = new ConverterLocator();
defaultLocator.set(Pattern.class, new RegExpPatternConverter());
return defaultLocator;
}
您可以简单地从 Wicket 8 向后移植转换器 类。您会发现这些附加到此提交:https://issues.apache.org/jira/browse/WICKET-6200(AbstractJavaTimeConverter 和您需要的任何子类 LocalDate, LocalDateTime、LocalTime 等)
当然,这对 DateTextField 没有帮助,因为它具有硬编码的 Date 类型参数。为此,您可以使用上述转换器创建自己的 sub类,或者使用常规标签和 TextField,并在全局注册转换器,如下所示:
@Override
protected IConverterLocator newConverterLocator() {
ConverterLocator converterLocator = new ConverterLocator();
converterLocator.set(LocalDateTime.class, new LocalDateTimeConverter());
converterLocator.set(LocalDate.class, new LocalDateConverter());
converterLocator.set(LocalTime.class, new LocalDateConverter());
return converterLocator;
}