为何session中存入对象后,修改对象的属性值后并没有再次存入session,session中存放的对象也发生改变?

本文讨论了Java后端开发中遇到的一个问题:在Session中保存的会员信息对象被意外修改。当对象属性被脱敏后,从Session中取出的对象属性值也被改变。原因在于Java对象的引用特性,当对象放入Map或Session时,保存的是对象的引用地址,而非副本。因此,对原对象的修改会影响到Session中的对象。解决办法是复制一份新的对象用于脱敏,以保持Session中对象的原始状态。
摘要由CSDN通过智能技术生成

遇到这样的一个业务场景:前端请求检查会员信息接口,后端用session保存会员信息以便后续业务使用。但输出的信息需要脱敏,在把会员信息对象存入session后,修改对象的属性值为脱敏值输出,但是在后续业务需要用到会员信息时再从session中获取,发现session中的对象的属性也被修改成了脱敏值,这是为什么呢?
大体代码如下:

@Data
public class User {
    private Integer id;
    private String name;
}
/**
 * 得到request对象
 */
public HttpServletRequest getRequest() {
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    return request;
}

/**
 * 保存session
 *
 * @param key
 * @param value
 */
public void setSessionAttr(String key, Object value) {
    HttpSession session = getRequest().getSession();
    session.setAttribute(key, value);
}

/**
 * 获取session值
 *
 * @param key
 * @return
 */
public <T> T getSessionAttr(String key) {
    HttpSession session = getRequest().getSession();
    return (T) session.getAttribute(key);
}
@RequestMapping("/test4")
public Object test4() throws Exception{
    User user = new User();
    user.setId(100);
    user.setName("王二狗");
    setSessionAttr("user",user);

    //脱敏
    user.setName("王*狗");
    return user;
}
@RequestMapping("/test6")
public void test6() throws Exception{
    User user = getSessionAttr("user");
    System.out.println("user: "+user);
}

测试结果如下:
在这里插入图片描述
发现明明没有再保存进入,但从session中获取出来的值却被改变了!
原因分析
session底层其实是用ConcurrentHashMap保存数据的,下面就以Map集合进行分析

@Test
public void test35() throws Exception{
    User user = new User();
    user.setName("王二狗").setAge(18);
    Map<String,User> map = new HashMap<>();
    map.put("user",user);
    System.out.println(map.get("user"));

    user.setName("王三狗").setAge(20);
    System.out.println(map.get("user"));
}

在这里插入图片描述
由此可见,在Map集合中保存的对象并不是对象本身,而是对象的引用地址。当对象放入Map集合后修改对象的属性值,然后再次从Map中取值,实际上是根据的引用地址去找此对象。同理,session中保存的数据也是一样。

参考:

  1. Tomcat Session总结及底层实现

  2. session中存放一个对象,只修改对象的属性,不将修改后的对象存放session,发现session中存放的对象也发生改变!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex·Guangzhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值