首页 > 数据库 >RedisTemplate进行对象序列化踩坑

RedisTemplate进行对象序列化踩坑

时间:2022-11-20 17:59:59浏览次数:31  
标签:BigDecimal 对象 buyCount private Integer import lombok 序列化 RedisTemplate

RedisTemplate 默认使用 JdkSerializationRedisSerializer 对对象进行序列化
RedisTemplate 相关源码如下:

private @Nullable RedisSerializer<?> defaultSerializer;

@SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;

@Override
public void afterPropertiesSet() {

    super.afterPropertiesSet();

    boolean defaultUsed = false;

    if (defaultSerializer == null) {

        defaultSerializer = new JdkSerializationRedisSerializer(
            classLoader != null ? classLoader : this.getClass().getClassLoader());
    }

    if (enableDefaultSerializer) {

        if (keySerializer == null) {
            keySerializer = defaultSerializer;
            defaultUsed = true;
        }
        if (valueSerializer == null) {
            valueSerializer = defaultSerializer;
            defaultUsed = true;
        }
        if (hashKeySerializer == null) {
            hashKeySerializer = defaultSerializer;
            defaultUsed = true;
        }
        if (hashValueSerializer == null) {
            hashValueSerializer = defaultSerializer;
            defaultUsed = true;
        }
    }

    if (enableDefaultSerializer && defaultUsed) {
        Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
    }

    if (scriptExecutor == null) {
        this.scriptExecutor = new DefaultScriptExecutor<>(this);
    }

    initialized = true;
}


这里自定义 RedisTemplate,使用 GenericJackson2JsonRedisSerializer,代码如下:

@Configuration
public class RedisConfig {

    //向容器中添加 **GenericJackson2JsonRedisSerializer** 对象
    @Bean(name = "springSessionDefaultRedisSerializer")
    public GenericJackson2JsonRedisSerializer getGenericJackson2JsonRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }

    //向容器中添加自定义的 **RedisTemplate**
    @Bean
    public RedisTemplate<String, Object> getRedisTemplate( RedisConnectionFactory connectionFactory) {
        //创建 **RedisTemplate **对象
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //设置 **RedisTemplate ** 的 **ConnectionFactory**
        redisTemplate.setConnectionFactory(connectionFactory);
        //设置 **RedisTemplate ** 的默认序列化器 **defaultSerializer**
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());

        //设置 **key**、**hashKey **的序列化器为 **StringRedisSerializer**
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);

        return redisTemplate;
    }
}


所遇异常:

1. org.springframework.data.redis.serializer.SerializationException: Could not write JSON: (was java.lang.NullPointerException) (through reference chain: com.atguigu.bookcity.pojo.CartItem["xj"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.atguigu.bookcity.pojo.CartItem["xj"])
2. org.springframework.data.redis.serializer.SerializationException: Could not write JSON: (was java.lang.NullPointerException) (through reference chain: com.atguigu.bookcity.pojo.OrderItem["xj"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.atguigu.bookcity.pojo.OrderItem["xj"])


原因:我定义的两个实体类 CartItemOrderItem 中有 getXXX() 方法,但没有对应的属性,而 GenericJackson2JsonRedisSerializer 序列化会调用 getXXX() 方法为相应属性赋值,故报错
原始实体类定义如下:

package com.atguigu.bookcity.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.math.BigDecimal;

/**
 * @author ycjstart
 * @create 2022-11-16 16:15
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class CartItem {

    private Integer id;

    private Book book;

    private Integer buyCount;

    private Integer userBean;


    public Double getXj() {
        BigDecimal bookPrice = BigDecimal.valueOf(book.getPrice());
        return  (bookPrice.multiply(new BigDecimal(buyCount)).doubleValue());
    }

}

package com.atguigu.bookcity.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.math.BigDecimal;

/**
 * @author ycjstart
 * @create 2022-11-16 16:18
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderItem {

    private Integer id;

    private Book book;

    private Integer buyCount;

    private Integer orderId;


    public OrderItem(Book book, Integer buyCount, Integer orderId) {
        this.book = book;
        this.buyCount = buyCount;
        this.orderId = orderId;
    }

    public Double getXj() {

        BigDecimal bookPrice = BigDecimal.valueOf(book.getPrice());
        return bookPrice.multiply(BigDecimal.valueOf(buyCount)).doubleValue();

    }

}


修改后实体类:

package com.atguigu.bookcity.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.math.BigDecimal;

/**
 * @author ycjstart
 * @create 2022-11-16 16:15
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class CartItem {

    private Integer id;

    private Book book;

    private Integer buyCount;

    private Integer userBean;


    public Double calculateXj() {
        BigDecimal bookPrice = BigDecimal.valueOf(book.getPrice());
        return  (bookPrice.multiply(new BigDecimal(buyCount)).doubleValue());
    }

}

package com.atguigu.bookcity.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.math.BigDecimal;

/**
 * @author ycjstart
 * @create 2022-11-16 16:18
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderItem {

    private Integer id;

    private Book book;

    private Integer buyCount;

    private Integer orderId;


    public OrderItem(Book book, Integer buyCount, Integer orderId) {
        this.book = book;
        this.buyCount = buyCount;
        this.orderId = orderId;
    }

    public Double calculateXj() {

        BigDecimal bookPrice = BigDecimal.valueOf(book.getPrice());
        return bookPrice.multiply(BigDecimal.valueOf(buyCount)).doubleValue();

    }

}


方法名修改后,异常解决

标签:BigDecimal,对象,buyCount,private,Integer,import,lombok,序列化,RedisTemplate
From: https://www.cnblogs.com/MuYg/p/16909051.html

相关文章

  • 自定义RedisTemplate<String, Object>
    说明:redisTemplate的keySerializer、hashKeySerializer设置为StringRedisSerializer,valueSerializer、hashValueSerializer设置为**genericJackson2JsonRedisSerializer**......
  • 46.通过字典和Series对象进行分组统计
     -----------------------------------------------------------------------------------------------------------------------------------------------------------......
  • ArrayList集合对象
     usingSystem;usingSystem.Collections;namespaceArrayList集合{classProgram{staticvoidMain(string[]args){//......
  • C++面向对象程序设计概念梳理
    写在前面:本篇文档是为了《C++面向对象程序设计》课程所写,包含了本课程考试可能会考的所有概念。当然,因为目的只是为了通过考试,所以我将这些概念已经尽量精简。如果你将下......
  • ES6之对象方法扩展
    对象扩展ES6新增了一些Object对象的方法1)Object.is比较两个值是否严格相等,与『===』行为基本一致(+0与NaN)2)Object.assign对象的合并,将源对象的所有可枚举属性......
  • Django ORM 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询
    DjangomodelORM数据表相关操作分析思路,创建数据表对于表操作,表之间的关联关系,必须理解他们之间的关系,对于编程很重要。可以看看映射关系、外键和relationship查询,至少明......
  • Java-02对象传递和返回
    Java-02对象传递和返回当你在“传递”一个对象的时候,你实际上是在传递它的引用1引用1.1传递引用当你将一个引用传给方法后,该引用指向的仍然是原来的对象:/***@Auth......
  • Scanner对象
    Scanner对象通过Scanner类来获取对象的输入。基本语法:Scanners=newScanner(System.in);通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我......
  • java——集合——Map集合——Entry键值对对象&Map集合遍历键值对方法
                                    Map集合遍历键值对方法Map集合遍历的第二种方式:使用Entry对象......
  • JavaScript基础知识——对象
    定义无序数据的集合,键值对的集合。写法构造函数letuser=newObject({name:'yang',age:100})字面量letuser={name:'yang',age:200}匿名对象console.l......