解决黑马点评项目中实现商铺缓存与数据库的双写一致问题出现的问题,LocalDateTime在项目中的使用(LocalDateTime与前端的时间戳互转)

解决黑马点评项目中实现商铺缓存与数据库的双写一致问题出现的问题:时间问题
2023-01-10 10:41:48.177 ERROR 1796 — [nio-8081-exec-2] com.hmdp.config.WebExceptionAdvice : org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: raw timestamp (1642069999999) not allowed for java.time.LocalDateTime: need additional information such as an offset or time-zone (see class Javadocs); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: raw timestamp (1642069999999) not allowed for java.time.LocalDateTime: need additional information such as an offset or time-zone (see class Javadocs)
at [Source: (PushbackInputStream); line: 9, column: 17] (through reference chain: com.hmdp.entity.Shop[“updateTime”])

Java的LocalDateTime 转为 前端的时间戳


/**
 * 由于 LocalDateTime 类型在转换 JSON 的时候,并不能被转换为字符串,使用 @JsonFormat 只能转换为指定的 pattern 类型,因此我们需要自定义一个序列化执行器
 * LocalDateTime 序列化(将 LocalDateTime类型 转换为 时间戳 返回给前端 )
 *
 */
public class LocalDateTimeSerializer implements ObjectSerializer {
    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
        if (object != null) {
            LocalDateTime localDateTime = (LocalDateTime) object;
            //将localDateTime转换为中国区(+8)时间戳。
            serializer.write(localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        } else {
            serializer.write(null);
        }
    }
}

前端的时间戳 转为 Java的LocalDateTime


/**
 * 由于 时间戳 并不能直接被 fastJSON 转换为 LocalDateTime 类型,因此我们需要自定义一个序列化执行器
 * LocalDateTime 反序列化(将前端传递的 时间戳 转换为 LocalDateTime 类型)
 *
 */
 
public class LocalDateTimeDeserializer implements ObjectDeserializer {

    @Override
    @SuppressWarnings("unchecked")
    public LocalDateTime deserialze(DefaultJSONParser parser, Type type, Object fieldName) {

        String timestampStr = parser.getLexer().numberString();

        if (timestampStr == null || "".equals(timestampStr)) {
            return null;
        }

        timestampStr = timestampStr.replaceAll("\"", "");

        long timestamp = Long.parseLong(timestampStr);
        if(timestamp == 0) {
            return null;
        }
        return Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
    }

    @Override
    public int getFastMatchToken() {
        return 0;
    }
}

使用

在这里插入图片描述

更改 SpringBoot 的 @RequestBody 为 fastJson 接收

我们在回写前端的时候,是使用 fastJson 进行转换的,但是在接受 Json 的时候,是使用 Spring 默认的 jackson 来接受的,所以这会导致,我们重写了 fastJson 的反序列化方法并未执行。前端传递时间戳给后端,后端报错400。

因此,我们需要更改 spring 默认提供的 jackson 为 fastJson

package com.hmdp.config;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    /**
     * springboot 默认使用的是 jackson 进行 requestBody 请求的封装,该项目切换为使用 fastJson 进行请求封装和响应
     * 配置 springboot 使用 fastJson 进行数据的请求接受和响应
     *
     */

    public HttpMessageConverter<String> stringConverter() {
        return new StringHttpMessageConverter(StandardCharsets.UTF_8);
    }

    public FastJsonHttpMessageConverter fastConverter() {
        //1、定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //2、添加fastJson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullNumberAsZero,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullBooleanAsFalse);

        fastJsonConfig.setCharset(StandardCharsets.UTF_8);
        //2-1 处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        //3、在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        return fastConverter;
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.clear();
        converters.add(stringConverter());
        converters.add(fastConverter());
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值