更换商品图片日期JSON格式报错 - 序列化与反序列化日期格式设置

报错信息

msg: "服务端异常,请联系管理员

JSON parse error: Cannot deserialize value of type java.util.Date from String "2023-11-13 13:13:35": not a valid representation (error: Failed to parse Date value '2023-11-13 13:13:35': Cannot parse date "2023-11-13 13:13:35": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSX', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.Date from String "2023-11-13 13:13:35": not a valid representation (error: Failed to parse Date value '2023-11-13 13:13:35': Cannot parse date "2023-11-13 13:13:35": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSX', parsing fails (leniency? null))↵ at Source: (PushbackInputStream); line: 1, column: 233 (through reference chain: com.java1234.entity.Product"hotDateTime")"

配置文件配置application.yml:

bash 复制代码
 
spring: 
    jackson:
        #字符串时间,用这行表示
        date-format: yyyy-MM-dd 
        #设置为东八区时间
        timezone: GMT+8
       
bash 复制代码
spring:
  # 配置日期格式化
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss  #时间戳统一转换为指定格式
    time-zone: GMT+8  # 时区修改为东8区

application.properties配置方式

bash 复制代码
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss	#时间戳统一转换为指定格式
spring.jackson.time-zone=GMT+8	# 时区修改为东8区

【注意】这里需要修改时区time-zone:数据库默认时区是格林尼治的时间,如果不设置,会比实际时间少8个小时(北京时间)。

项目场景:

前端画面上有一个可以选择年月的日期选择器,代码如下:

bash 复制代码
      <el-form-item label="统计月份" prop="billsDate" v-if="isShowMonth">
        <el-date-picker clearable size="small"
                        v-model="queryParams.billsDate"
                        type="month"
                        value-format="yyyy-MM"
                        placeholder="请选择统计月份"
                        :disabled="inputDisable">
        </el-date-picker>
      </el-form-item>

选择的数据使用post请求将数据传递给后端

问题描述

后端接收的时候报如下错误

JSON parse error: Cannot deserialize value of type java.util.Date from String "2022-01":

后端接收的实体类如下

bash 复制代码
    /**
     * 客户ID
     */
    private Long companyId;
 
    /**
     * 客户code
     */
    private String companyCode;
 
    /**
     * 账单统计类型
     */
    private Integer billStatisticsType;
 
    /**
     * 账单时间
     */
    private Date billsDate;
   

原因分析:

因为传入的参数是 String 类型的,而用来接收参数的项目的属性是 java.util.Date 类型的,类型无法转换。

springboot默认采用jackson,而jackson只能识别以下几种日期格式

"yyyy-MM-dd'T'HH:mm:ss.SSSZ"; "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; "yyyy-MM-dd"; "EEE, dd MMM yyyy HH:mm:ss zzz"; long类型的时间戳(毫秒时间戳)

解决方案:

所以在接收到数据的时候,需要通过jackson把数据转化。jackson转化默认的时间格式 'yyyy-MM-dd'T'HH:mm:ss.SSS',所以就会出现异常,所以要设置时区的格式为"yyyy-MM"。

添加@JsonFormat注解,来说明接收格式

代码如下

bash 复制代码
    /**
     * 客户ID
     */
    private Long companyId;
 
    /**
     * 客户code
     */
    private String companyCode;
 
    /**
     * 账单统计类型
     */
    private Integer billStatisticsType;
 
    /**
     * 账单时间
     */
    @JsonFormat(pattern = "yyyy-MM")
    private Date billsDate;

SpringBoot中日期时间类型的序列化与反序列化

目录

1、背景

2、序列化时间戳

3、反序列化时间戳

4、使用示例

1、背景

在SpringBoot开发web

应用微服务时,常用Date类型表示日期时间,JDK8之后,可以使用Instant类型来表示时间戳,并持久化到数据库中。也有直接使用Long类型存储日期时间或时间戳的,但这种方式存储到数据库后,对于DBA

或运维查询数据库时,不太友好,没法直接看出来是什么日期或时间。大多数时候会使用Instant类型来表示时间戳。

在前后端分离的开发架构中,对于日期时间类型,后端接口在返回给前端时,需要将Instant类型转换为前端需要的时间戳即长整型Long(可序列化的类型),而前端一般也会提交时间戳类型给后端,后端需要将时间戳的长整型Long

转换为Instant类型。即需要实现对日期时间进行序列化和反序列化。SpringBoot框架中,实现对日期时间进行序列化和反序列化,只需要实现相应的接口即可完成。

序列化是将一个对象转换成字节序列的过程,可以将这些字节序列存储在磁盘或通过网络传输。反序列化是将字节序列转换回对象的过程。

2、序列化时间戳

将Instant类型转换为前端需要的长整型Long,可以通过继承JsonSerializer类,实现serialize方法即可。

bash 复制代码
package com.fandou.component.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.Instant;

/**
 * Instant序列化为Long类型
 */
public class InstantToLongSerializer extends JsonSerializer<Instant> {
    @Override
    public void serialize(Instant value, JsonGenerator generator, SerializerProvider serializers) throws IOException {
        // 通过JSON生成器,将要序列化的Instant类型对象即value的时间戳值写入为数值,即前端需要的长整型
        generator.writeNumber(value.toEpochMilli());
    }
}

3、反序列化时间戳

复制代码
	同样,将长整型Long转换为Instant类型,可以通过继承JsonDeserializer类,实现deserialize方法即可。
bash 复制代码
package com.fandou.component.json;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.time.Instant;

/**
 * Long反序列化为Instant类型
 *
 */
public class LongToInstantDeserializer extends JsonDeserializer<Instant> {
    @Override
    public Instant deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        // 从JSON初始化器中读取对应的长整型时间错值,使用Instant的ofEpochMilli初始化为Instant类型返回
        return Instant.ofEpochMilli(jsonParser.getValueAsLong());
    }
}

4、使用示例

使用@JsonSerialize注解或@JsonDeserialize注解标记需要序列化或反序列化的对象属性上,注解中的using属性值指定为步骤2或步骤3的序列化类或反序列化类型即可。在运行的过程中,SpringBoot

框架会自动完成日期时间的序列化和反序列化。

bash 复制代码
package com.example.demo.vo;

import com.fandou.component.json.InstantToLongSerializer;
import com.fandou.component.json.LongToInstantDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import lombok.Getter;
import lombok.Setter;

import java.time.Instant;

/**
 * 用户VO对象
 *
 * 
 */
@Setter
@Getter
public class User {
    /**
     * 主键id
     */
    private Long id;

    /**
     * 用户账号
     */
    private String userAccount;

    /**
     * 用户昵称
     */
    private String nickname;

    /**
     * 创建时间:使用@JsonSerialize注解和@JsonDeserialize注解实现创建时间属性的序列化和反序列化
     */
    @JsonSerialize(using = InstantToLongSerializer.class)
    @JsonDeserialize(using = LongToInstantDeserializer.class)
    private Instant createTime;
}
相关推荐
IDIOT___IDIOT16 小时前
JSON-RPC 2.0 与 MCP 协议:从消息格式到进程通信 大模型MCP
rpc·大模型·json·agent·mcp
憧憬成为原神糕手18 小时前
Playwright、Selenium、DrissionPage 与 JSON 接口怎么选?
数据库·selenium·json
SelectDB技术团队19 小时前
Apache Doris 4.1:面向 AI & Search 的统一数据底座怎么选?向量检索 + 全文搜索 + 100MB JSON 完整能力拆解
人工智能·json·apache doris
进击切图仔20 小时前
VS Code 调试 launch.json 解析
json
码智社1 天前
JSON 零基础到资深全体系教程
java·json
五阿哥永琪2 天前
MySQL中操作json的函数!
数据库·mysql·json
用户7783366132113 天前
SERP API JSON Schema 演进版本管理实战
json·api
IT小盘4 天前
14-让大模型稳定输出JSON-Prompt约束与结构化输出
windows·json·prompt
赵庆明老师5 天前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
红叶舞6 天前
成数据绑定对象,在应用程序中处理完数据后,将更新的数据序列化为JSON传回远端服务器,很多移动应用使用了这种模式处理服务器端的数据。 ...
运维·服务器·json