【问题标题】:How to use CustomDateEditor and DateTimeFormat at the same time in spring?春季如何同时使用CustomDateEditor和DateTimeFormat?
【发布时间】:2020-11-12 03:26:56
【问题描述】:
import org.springframework.format.annotation.DateTimeFormat;

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date etd;

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date eta;

此代码运行良好。但是我发现当时间为空字符串时会抛出异常,所以我添加了这个:

@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setLenient(false);
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

现在空字符串转换为null,但只使用“yyyy-MM-dd”,忽略小时和分钟。

例如eta,在我添加InitBinder之前,值是'2020-11-11 11:11:11',添加之后是'2020-11-11 00:00:00'。

如何让spring继续使用DateTimeFormat注解上的格式?

我发现了这个问题,但他似乎没有使用 DateTimeFormat :How to handle different date formats in Spring MVC controller?

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    由于 Spring 框架 5.3.5@DateTimeFormat 支持定义一个备用模式列表,用于在无法使用主要模式解析时解析日期时间。这意味着您可以简单地这样做:

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date etd;
    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss",fallbackPatterns = "yyyy-MM-dd")
    private Date eta;
    

    【讨论】:

      【解决方案2】:

      我认为您不能同时使用两者,因为系统只会选择其中一个,但您可以做的是扩展标准行为并添加空字符串处理。 由于我喜欢基于 @DateTimeFormat 注释的声明式解析字符串的方式,我将分享代码,展示扩展默认功能是多么容易。 因此,首先使用 Spring 使用 AnnotationFormatterFactorys 创建格式化程序来格式化和解析使用特定注释注释的字段的值。 @DateTimeFormat 注释有几个AnnotationFormatterFactorys,但其中一个解析和格式化java.util.Dates 是DateTimeFormatAnnotationFormatterFactory,所以我们需要做的就是覆盖它,添加我们的自定义处理并注册格式化程序。通过WebMvcConfigurationSupport 可以很简单地做到这一点。

      @Configuration
      public class WebConfig extends WebMvcConfigurationSupport {
      
          @Override
          protected void addFormatters(FormatterRegistry registry) {
              registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory(){
                  @Override
                  public Parser<?> getParser(DateTimeFormat annotation, Class<?> fieldType) {
                      var defaultParser = super.getParser(annotation, fieldType);
                      return (Parser<Object>) (text, locale) -> {
                          // if the text value is empty just return null and do not try to parse
                          if(!StringUtils.hasText(text)){
                              return null;
                          }
                          return defaultParser.parse(text, locale);
                      };
                  }
              });
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        Date 类非常过时(双关语)。请切换到包java.time 并使用Temporal 接口的实现之一。在您的情况下,您应该查看 LocalDateLocalDateTime 类。然后您的@DateTimeFormat 将正常工作

        【讨论】:

          猜你喜欢
          • 2013-10-01
          • 2019-03-31
          • 1970-01-01
          • 1970-01-01
          • 2012-08-27
          • 1970-01-01
          • 2017-10-06
          • 1970-01-01
          • 2020-02-23
          相关资源
          最近更新 更多