Spring JPA为什么将有效日期转换为无法识别的格式化字符串?

时间:2019-07-09 04:05:20

标签: spring rest http datetime jpa

我用POST端点设置了一个Spring Microservice应用程序,该应用程序接收一个RequestBody对象,该对象包含一个“ java.util.Date”字段。在我的其他应用中,当我向POST端点发送请求时,JSON中的日期看起来很好,格式为“ 2019-06-20T13:33:47.487-07:00”,但是当我的微服务收到请求时,它将日期字符串转换为以下内容:“ Jun 20,2019 1:33:47 PM”并告诉我“无法从字符串” Jun 20,2019 1:33:47 PM“反序列化类型java.util.Date的值:不是有效的表示形式。”

我玩过不同的注释,包括“ @Temporal(TemporalType.TIMESTAMP)”和“ @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)”。还尝试过手动设置JSONFormat,但这不是一个解决办法,因为输入日期字符串正以某种方式重新解释。

这是微服务POST端点:

@PostMapping(path = "/orders/create")
public ResponseEntity createOrder(@RequestBody final HubOrder hubOrder) {
    List<OrderLineitem> orderLineitem = orderService.hubOrderToOrderLineitems(hubOrder);
    repository.saveAll(orderLineitem);
    return ResponseEntity.created().build();
}

还有豆子:

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class HubOrder {
    private BigInteger id; 
    private Date created; 
    private String lastModifiedBy; 
    private List<HubLineitem> lineitems;
}

然后我从应用程序中找到端点,如下所示:

HubOrder hubOrder = createHubOrderFromOrder(order);
Gson gson = new Gson();
HttpPost request = new HttpPost("http://localhost:8888/orders/create");
StringEntity params = new StringEntity(gson.toJson(hubOrder));
HttpClient httpClient = HttpClientBuilder.create().build();


request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);

其中hubOrder.getCreated()==“ 2019-06-20T13:33:47.487-07:00”

我的微服务中的错误是“ 2019-07-08 20:50:47.663 WARN 2400 --- [nio-8888-exec-2] .wsmsDefaultHandlerExceptionResolver:已解决[org.springframework.http.converter.HttpMessageNotReadableException: JSON解析错误:无法从字符串“ Jun 20,2019 1:33:47 PM”中反序列化类型java.util.Date的值:不是有效的表示形式(错误:无法解析日期值'Jun 20,2019 1:33: 47 PM':无法解析的日期:“ 2019年6月20日下午1:33:47”);嵌套异常为com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串“ Jun反序列化类型java.util.Date的值20,2019 1:33:47 PM“:不是有效的表示形式(错误:无法解析日期值'Jun 20,2019 1:33:47 PM':无法解析的日期:” Jun 20,2019 1:33:47 PM ”) “

2 个答案:

答案 0 :(得分:1)

请尝试在Date created的{​​{1}}字段中添加以下内容;

HubOrder

反序列化默认取决于配置而采用不同的格式,似乎您的语言环境会影响它,如here所述。要自定义行为,您必须利用以上注释。或将其应用于所有情况,请执行以下操作;

  • 要么使用以下模式实例化gson;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MMM dd, yyyy hh:mm:ss aaa")
    private Date created
    
  • 或为Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") .create(); 类型传递自定义适配器

    Date

    然后

    public class GsonDateAdapter implements JsonSerializer<Date>,JsonDeserializer<Date> {
    
        private final DateFormat dateFormat;
    
        public GsonUTCDateAdapter() {
          dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        }
    
        @Override public synchronized JsonElement serialize(Date date,Type type,JsonSerializationContext jsonSerializationContext) {
            return new JsonPrimitive(dateFormat.format(date));
        }
    
        @Override public synchronized Date deserialize(JsonElement jsonElement,Type type,JsonDeserializationContext jsonDeserializationContext) {
          try {
            return dateFormat.parse(jsonElement.getAsString());
          } catch (ParseException e) {
            throw new JsonParseException(e);
          }
        }
    }
    

答案 1 :(得分:1)

您应该编写函数setCreated()并查看输入,然后使用jsonFormat将其转换为:D