来自 REST 的 @DateTimeFormat 变量给出 null

Posted

技术标签:

【中文标题】来自 REST 的 @DateTimeFormat 变量给出 null【英文标题】:@DateTimeFormat variable from REST gives null 【发布时间】:2020-04-11 23:52:25 【问题描述】:

我已经看到How to use LocalDateTime RequestParam in Spring? I get "Failed to convert String to LocalDateTime",但我仍然遇到问题。

所以编写一个带有 rest api 的 Spring Boot 应用程序。

控制器是

@RequestMapping(value = "/api/v1/climates/locationdates/location/sdate/edate", method = RequestMethod.GET)
   public ResponseEntity<Object> getClimate(@PathVariable("location") long location,
                                             @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime sdate, 
                                             @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime edate) 
      System.out.println("CONTROLLER location is " + location + " start is " + sdate + " end is " + edate);           
      return new ResponseEntity<>(climateService.getClimatesByLocationAndDates(location, sdate, edate), HttpStatus.OK);
   

当我使用 curl 时(使用与创建记录相同的日期格式)

curl -k -w "\n" -H "授权:Bearer $TOKEN" https://mint191:8453/api/v1/climates/locationdates/1/2019-12-17T11:30:00/2019-12-17T11:55:00

我得到了回应

"timestamp":"2019-12-19T11:05:21.707+0000","status":500,"error":"内部 服务器错误","message":"值不能为空!;嵌套异常是 java.lang.IllegalArgumentException:值不能是 空!","路径":"/api/v1/climates/locationdates/1/2019-12-17T11:30:00/2019-12-17T11:55:00"

在日志中

CONTROLLER location is 1 start is null end is null

请求和响应完成

2019-12-19 11:05:21.668 错误 21113 --- [nio-8453-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] :Servlet.service() for 带有路径 [] 的上下文中的 servlet [dispatcherServlet] 引发异常 [请求处理失败;嵌套异常是 org.springframework.dao.InvalidDataAccessApiUsageException:值必须 不能为空!;嵌套异常是 java.lang.IllegalArgumentException: 值不能为空!] 有根本原因

java.lang.IllegalArgumentException:值不能为空!在 org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]

模型是

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "climate_gen")
private long id;

private float temperature;
private float humidity;
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime date;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "location_id", nullable = false)
private Location location;

所以日期字符串 2019-12-17T11:55:00 没有被转换为 LocalDatTime 对象。我做错了什么?

PS。使用不同的模式只是为了看看一个是否有效。

【问题讨论】:

我怀疑问题出在你的 DateTimeFormat 上,你的参数很可能是 null 【参考方案1】:

将@PathVariable 添加到 sdate 和 edate 以从 url 访问值,如下所示:

@RequestMapping(value = "/api/v1/climates/locationdates/location/sdate/edate", method = RequestMethod.GET)
    public ResponseEntity<Object> getClimate(@PathVariable("location") long location,
            @PathVariable("sdate") @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime sdate,
            @PathVariable("edate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime edate) 

         System.out.println("CONTROLLER location is " + location + " start is " + sdate + " end is " + edate);           
         return new ResponseEntity<>(climateService.getClimatesByLocationAndDates(location, sdate, edate), HttpStatus.OK);
   

【讨论】:

我显然误解了我引用的***条目。非常感谢@Nitika。【参考方案2】:

我会建议几种解决方法。

    不要只传递 LocalDateTime 变量,而是将其包装在某个类中(连同其他参数),并在您的包装类中将其注释为:

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")

    将其作为字符串传递并在服务器端使用 DateTimeFormatter 对其进行解析

【讨论】:

【参考方案3】:

缺少的是:

@PathVariable("sdate")
@PathVariable("edate")

因此它们保持为空。 ;)

提示:如果不起作用,请从简化的原型开始;理想情况下是单元测试。 然后可以使用 LocalDateTime 等连续添加/删除元素,例如格式化程序注释。

ISO 格式似乎也是标准格式(不确定 ms),ZonedDateTime 可能对用户更友好。

【讨论】:

以上是关于来自 REST 的 @DateTimeFormat 变量给出 null的主要内容,如果未能解决你的问题,请参考以下文章

使用@DateTimeFormat 的日期时间解析问题

如何解析从 Intl.DateTimeFormat 生成的日期字符串

dubbo开启rest协议后,date属性返回是时间戳,如何格式化yyyy-MM-dd?

TimeZone 选项在 Intl.DateTimeFormat() 中究竟做了啥

Spring @DateTimeFormat 转换错误与夏令时

@DateTimeFormat注解