首页 > 解决方案 > Spring RequestBody 无法正确解析 datetime 时区

问题描述

我有一个简单的休息服务来存储时间范围,但是,Spring 无法正确解析带有时区的日期时间格式。

实体是

@Data
@Entity
public class TimeRange {
@Setter(AccessLevel.NONE)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = true)
private LocalDateTime startTime;

@Column(nullable = true)
private LocalDateTime endTime;
}

控制器是:

@PostMapping(path = "/time", consumes = "application/json", produces = "application/json")
public Boolean setTime(@RequestBody TimeRange timeRange) {
    timeRangeRepository.save(timeRange);
    return true;
}

而实际的要求是

url = f'http://localhost/api/time'
data = {
  "startTime": "2019-12-03T19:58:29.047820+08:00",
  "endTime": "2019-12-04T19:58:29.047820+08:00"}
resp = requests.post(url, json=data, timeout=10)
pprint(resp.json())

spring报错说:

 esolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: 
Cannot deserialize value of type `java.time.LocalDateTime` from String "2019-12- 

03T19:58:29.047820+08:00": 无法反序列化 java.time.LocalDateTime: (java.time.format.DateTimeParseException) 文本 '2019-12-03T19:58:29.047820+08:00' 无法解析,在索引 26 处找到未解析的文本;嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException:无法反序列化 java.time.LocalDateTime来自字符串“2019-12-03T19:58:29.047820+08:00”的类型值:无法反序列化 java。 time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2019-12- 03T19:58:29.047820+08:00' 无法解析,在索引 26 处找到未解析的文本

标签: javaspringdatetime

解决方案


您有一个带有偏移量的日期,如果您的所有日期都采用相同的格式,您可以像这样创建一个自定义反序列化器

public class CustomLocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
   private static final long serialVersionUID = 1L;

    public CustomLocalDateTimeDeserializer () {
        this(null);
    }

    protected CustomLocalDateTimeDeserializer (Class<?> vc) {
        super(vc);
    }

    @Override
    public LocalDateTime deserialize(JsonParser arg0, DeserializationContext arg1)
        throws IOException, JsonProcessingException {
        return LocalDateTime.parse(arg0.getValueAsString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    }

}

并用注释您的字段@JsonDeserialize

@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
private LocalDateTime startTime;

@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
private LocalDateTime endTime;

如果你想用相同的格式序列化你的日期,你必须创建一个自定义序列化器


推荐阅读