【问题标题】:How can I bring Wicket 7 to work with java.time from Java 8?如何让 Wicket 7 与 Java 8 中的 java.time 一起使用?
【发布时间】:2017-01-02 21:25:11
【问题描述】:

我有很多 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 );

【问题讨论】:

    标签: java converter wicket


    【解决方案1】:

    您可以将LocalDate 等模型包装在IModel&lt;java.util.Date&gt; 中,例如

    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&lt;T&gt;

    如果您使用此扩展程序而不是常规的 CompoundPropertyModel,它将检测字段何时为 LocalDate 并为组件(如您的 DateTextField)提供模型,这些组件被包装成看起来像 java.util.Date 模型。

    我给你的代码 sn-p 虽然很脏(你可能不应该让模型对象推断它的类型),因为我只是提供它来说明一般机制,所以我建议你设计自己的方法来推断预期对象的类型(例如,您可以检查 Component 参数是否为 DateTextField),但这是我可以想象的解决方案的大体方向。

    【讨论】:

    • 你能提供一个确切的实现吗?我无法按照您的提示创建this question
    【解决方案2】:

    您可以注册自己的转换器:

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

    相关:https://issues.apache.org/jira/browse/WICKET-6200

    【讨论】:

    • 这是正确的......但不能解决我使用诸如 DateTextField、DatePicker 等 Wicket 小部件的要求。
    • 对于 DateTextField 和类似的 WiseTree 的模型包装器是正确的答案。
    【解决方案3】:

    您可以简单地从 Wicket 8 反向移植转换器类。您会发现这些附加到此提交:https://issues.apache.org/jira/browse/WICKET-6200(AbstractJavaTimeConverter 以及您需要的 LocalDate、LocalDateTime、LocalTime 等的任何子类)

    当然,这对 DateTextField 没有帮助,因为它具有硬编码的 Date 类型参数。为此,您可以使用上述转换器创建自己的子类,也可以使用常规的 Label 和 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      • 2014-07-13
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多