项目中copy List 数据,解决修改值后改变原值问题(SerialKiller)

在copy 对像时,发现改变copy对象的属性值时,都会改变原值,方法如下:

List<A> a ;//a为方法参数中传进来的list;

方法1:

List<A> b = new ArrayList<A>(a);

方法2:

List<A> b = new ArrayList<A>(Arrays.asList(new A[a.size()]));
Collections.copy(b, a);

以上方法copy完毕后,经测试都会改变原list的对象属性值,放弃;

使用以下方法解决了此问题

/**
     * list中的对象必须实现序列化接口 执行序列化和反序列化  进行深度拷贝  
     * @param srcList
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    @SuppressWarnings("unchecked")
    private <T> List<T> deepCopy(List<T> srcList) throws IOException, ClassNotFoundException {  
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
        ObjectOutputStream out = new ObjectOutputStream(byteOut);  
        out.writeObject(srcList);  
 
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
        ObjectInputStream in = new ObjectInputStream(byteIn);  
        List<T> destList = (List<T>) in.readObject();  
        return destList;  
    }


根据的2015年11月发现的序列化漏洞修改为:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.struts2.ServletActionContext;
import org.nibblesec.tools.SerialKiller;


/**
  * list中的对象必须实现序列化接口 执行序列化和反序列化  进行深度拷贝 
  * @param srcList
  * @return
  * @throws IOException
  * @throws ClassNotFoundException
  * @throws ConfigurationException
  */
 @SuppressWarnings("unchecked")
 private <T> List<T> deepCopy(List<T> srcList) {
  List<T> destList = null;
  ByteArrayOutputStream byteOut = null;
  ObjectOutputStream out = null;
  ByteArrayInputStream byteIn  = null;
  ObjectInputStream ois = null;
  try {
   byteOut = new ByteArrayOutputStream();
   out = new ObjectOutputStream(byteOut);
   out.writeObject(srcList);
   byteIn = new ByteArrayInputStream(byteOut.toByteArray());
   ois = new SerialKiller(byteIn, "config/serialkiller.conf");
   //原方法放弃
   // ObjectInputStream in = new ObjectInputStream(byteIn);
   // destList = (List<T>) in.readObject();
   destList = (List<T>) ois.readObject();
  } catch (IOException e) {
   LOGGER.error("对象中包含没有继承序列化的对象: " + e.getMessage());
  } catch (ConfigurationException e) {
   LOGGER.error("对象中包含没有继承序列化的对象: " + e.getMessage());
  } catch (ClassNotFoundException e) {
   LOGGER.error("对象中包含没有继承序列化的对象: " + e.getMessage());
  }
  finally{
   try {
    if(ois != null){ois.close();ois =null;}
    if(byteIn != null){byteIn.close();byteIn = null;}
    if(out !=null ){out.close();out = null;}
    if(byteOut != null ){byteOut.close(); byteOut = null;}
   } catch (IOException e) {
    LOGGER.error("对象关闭失败: " + e.getMessage());
   }
  }

  return destList;
 }

转载于:https://my.oschina.net/farces/blog/277488

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值