报错原因

最近在项目中引入了jjwt的依赖,来生成token

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.12.6</version>
</dependency>

但是在生成token是报错了,大概原因是在实体类中有jdk8的时间类型的字段,jackson序列化默认不支持jdk8的时间类型

在spring-boot-starter-web中有jackson的依赖,但还是报错

猜想应该是使用了jackson默认的序列化方式导致的

解决办法

jackson

序列化:在构建 JWT 之前,将 LocalDateTime 转换为字符串或时间戳。
反序列化:在解析 JWT 后,从字符串或时间戳重新创建 LocalDateTime 对象。

在Jackson 中提供了 JavaTimeModule 模块,可以注册到 ObjectMapper 中以支持这些类型的自动转换。

引入JavaTimeModule的依赖,其实spring-boot-starter-web中自带有

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.15.2</version> <!-- 请根据需要选择版本 -->
</dependency>

配置 ObjectMapper:创建并配置一个 ObjectMapper 实例,注册 JavaTimeModule

    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }

    public static String genAccessToken(Object object) {
        return Jwts.builder()
                // 设置头部信息header
                .header()
                .add("typ", "JWT")
                .add("alg", "HS256")
                .and()
                // 设置自定义负载信息payload
                .claims().add(mapper.convertValue(object,Map.class)).and()
                // 令牌ID
                .id(UUID.randomUUID().toString())
                // 过期日期
                .expiration(Date.from(Instant.now().plusSeconds(ACCESS_EXPIRE)))
                // 签发时间
                .issuedAt(new Date())
                // 主题
                .subject(SUBJECT)
                // 签发者
                .issuer(JWT_ISS)
                // 签名
                .signWith(KEY, ALGORITHM)
                .compact();
    }

也可以提前转换为非jdk8时间类型

Map<String, Object> claims = BeanUtil.beanToMap(user);

使用fastjson

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐