Spring提供的org.springframework.util.Base64Utils类,先会检测JDK里是否自带java.util.Base64,如果不带,则使用的是apache提供的org.apache.commons.codec.binary.Base64:
 
 
经过一段时间的生产试运行来看,在多线程环境中Base64Utils会出各种异常,比如这样的异常:
java.lang.ArrayIndexOutOfBoundsException: null 
at org.apache.commons.codec.binary.BaseNCodec.readResults(BaseNCodec.java:209) 
at org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:324) 
at org.springframework.util.Base64Utils$CommonsCodecBase64Delegate.decode(Base64Utils.java:164)
at org.springframework.util.Base64Utils.decodeFromString(Base64Utils.java:124)
...
java.lang.NullPointerException: null 
at java.lang.System.arraycopy(Native Method) 
at org.apache.commons.codec.binary.BaseNCodec.readResults(BaseNCodec.java:209) 
at org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:324) 
at org.springframework.util.Base64Utils$CommonsCodecBase64Delegate.decode(Base64Utils.java:164) 
at org.springframework.util.Base64Utils.decodeFromString(Base64Utils.java:124)
...
又或者没抛异常,但Base64Utils.decodeFromString解出的数据已经不准确了,比如此时用它解码出的数据或秘钥来进行解密的话,会出类似如下异常:
  javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
 at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
 at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
 at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)
 at javax.crypto.Cipher.doFinal(Cipher.java:2087)
...
但具体由哪个类引起的并发,原因有待分析,可能与JDK版本、org.apache.commons.codec.binary.Base64、java.util.Base64都有关系,不管问题出在哪,在使用Base64Utils的地方,加上同步应该即可解决:
 synchronized (Base64Utils.class) {
            key = Base64Utils.decodeFromString(keyBase64);
}
 synchronized (Base64Utils.class) {
            rtnValue = Base64Utils.encodeToString(data);
}
或者不使用org.springframework.util.Base64Utils,而是直接使用apache提供的org.apache.commons.codec.binary.Base64(相应方法:Base64.decodeBase64(keyBase64),Base64.encodeBase64String(data)),并发环境下目前发现没有问题,代码参见附件!!
 
由于synchronized 同步会引起性能问题,如果直接使用org.apache.commons.codec.binary.Base64
没有问题的话,还是采用这种方式吧
 
 
 
 
 

附件列表

org.springframework.util.Base64Utils线程安全问题的更多相关文章

  1. Servlet, Struts2和SpringMVC 并发访问线程安全问题

    第一部分: Servlet不是线程安全的. 要解释Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP ...

  2. Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间以及单例多例的区别、SSH线程安全问题

    首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的.在这里需要提醒一下,如果我们在class中没有显示的声 ...

  3. 《day15---多线程安全问题_JDK1.5的锁机制》

    //15同步问题的分析案例以及解决思路 //两个客户到一个银行去存钱,每个客户一次存100,存3次. //问题,该程序是否有安全问题,如果有,写出分析过程,并定于解决方案. /* 发现运行结果: su ...

  4. SimpleDateFormat 的线程安全问题与解决方式

    SimpleDateFormat 的线程安全问题 SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的详细类. 它同意格式化 (date -> text).语法分析 (te ...

  5. SimpleDateFormat使用和线程安全问题

    SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (date -> text).语法分析 (text -> date)和标准化. Simpl ...

  6. SimpleDateFormat时间格式化存在线程安全问题

    想必大家对SimpleDateFormat并不陌生.SimpleDateFormat 是 Java 中一个非常常用的类,该类用来对日期字符串进行解析和格式化输出,但如果使用不小心会导致非常微妙和难以调 ...

  7. Lock锁方式解决线程安全问题

    在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...

  8. 关于SimpleDateFormat安全的时间格式化线程安全问题

    想必大家对SimpleDateFormat并不陌生.SimpleDateFormat 是 Java 中一个非常常用的类,该类用来对日期字符串进行解析和格式化输出,但如果使用不小心会导致非常微妙和难以调 ...

  9. Java并发编程基础-线程安全问题及JMM(volatile)

    什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...

随机推荐

  1. 关于Excel做表小知识记录

    关于Excel做表小知识记录 最近使用Excel做了一系列的报表,觉得这是个很神奇的东西哈哈哈,以前我可是一想到Excel就开始头疼的人...  能用代码或者SQL语句解决的问题绝不会愿意留在Exce ...

  2. Redis入门(三)-Redis的安装及操作key的命令介绍

    前两节对Redis做了一些详细的介绍,那么接下来开始我们就正式进入Redis的学习阶段. 安装Redis Windows下安装redis非常方便, 下载压缩包解压即可使用. 链接:https://pa ...

  3. HttpModules配置事项

    前沿:还是那句话 ASP.NET管道,浏览器 - isAPI32.dll - HttpModules - HttpHandler - 返回客户端Web.Config:<httpModules&g ...

  4. python中list常用的方法

    Python 列表    list    (以下内容为比较初级适合小白查看的笔记)   一.介绍: 列表是Python中内置有序.可变序列,列表的所有元素放在一对中括号“[]”中,并使用逗号分隔开: ...

  5. 网络协议 15 - P2P 协议

    大家说起种子,应该都知道是用来下载资源的.那么资源下载都有哪些方式?种子下载又有什么优势呢? 下载电影的两种方式     第一种是通过 HTTP 进行下载.这种方式,有过经历的人应该体会到,当下载文件 ...

  6. Python3 进程、线程和协程

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 进程.线程和协程的对比 1.定义对比 进程:是系统进行资源分配的基本单位,每启动一个进程,操作系统都需要为其分配运 ...

  7. 查询物料单位PAC成本

    select cpp.period_name 期间名称, ccga.organization_id 组织ID, ood.ORGANIZATION_CODE 组织代码, OOD.ORGANIZATION ...

  8. Cesium专栏-视频投影(附源码下载)

    Cesium Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精 ...

  9. Spring Boot 2 + Thymeleaf:服务器端表单验证

    表单验证分为前端验证和服务器端验证.服务器端验证方面,Java提供了主要用于数据验证的JSR 303规范,而Hibernate Validator实现了JSR 303规范.项目依赖加入spring-b ...

  10. MySQL基础之常用函数

    数学函数的使用 常用数学函数 函数 作用 函数 作用 ceil() 进一取整 abs() 取绝对值 floor() 舍掉小数部分 power() 幂运算 round() 四舍五入 pi() 圆周率 t ...