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. 无需重新安装软件,将软件从C盘移至其他盘(mklink)

    事先说明,这篇博文算是视频的文字转载版,来源为该视频的五分钟后内容→https://www.bilibili.com/video/av78397784/ 如何拯救标红的C盘[高玩] 有时候安装软件会手 ...

  2. tensorflow convert_variables_to_constants

    在使用tf.train.Saver函数保存模型文件的时候,是保存所有的参数信息,而有些时候我们并不需要所有的参数信息.我们只需要知道神经网络的输入层经过前向传播计算得到输出层即可,所以在保存的时候,我 ...

  3. @Import与@ImportResource注解的解读

    前言 在使用Spring-Cloud微服务框架的时候,对于@Import和@ImportResource这两个注解想必大家并不陌生.我们会经常用@Import来导入配置类或者导入一个带有@Compon ...

  4. Elasticsearch 6.x版本全文检索学习之聚合分析入门

    1.什么是聚合分析? 答:聚合分析,英文为Aggregation,是es除搜索功能外提供的针对es数据做统计分析的功能.特点如下所示: a.功能丰富,提供Bucket.Metric.Pipeline等 ...

  5. PHP mysqli_fetch_object MySQLi 函数

    定义和用法 mysqli_fetch_object - 返回结果集的当前行作为对象 版本支持 PHP4 PHP5 PHP7 不支持 支持 支持 语法 mysqli_fetch_object ( mys ...

  6. Java 类集初探

    类集 类集:主要功能就是Java数据结构的实现(java.util) 类集就是动态对象数组(链表也是动态数组) Collection 接口* Collection是整个类集之中单值保存的最大 父接口 ...

  7. 记录:c#实现微信,支付宝扫码支付(一)

    因为公司系统业务需要,这几天了解了一下微信和支付宝扫码支付的接口,并用c#实现了微信和支付宝扫码支付的功能. 微信支付分为6种支付模式:1.付款码支付,2.native支付,3.jsapi支付,4.a ...

  8. AI-Web1靶机渗透

    先上一张图: 靶机信息及地址:https://www.vulnhub.com/entry/ai-web-1,353/ 下载到靶机后,在VMware里打开,kali使用arp-scan -l 扫到 在浏 ...

  9. Linux find 用法和参数

    Linux中find常见用法 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数: ...

  10. opencv-python 图像处理(五)

    Canny边缘检测 1) 使用高斯滤波器,以平滑图像,滤除噪声. 2) 计算图像中每个像素点的梯度强度和方向. 3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测 ...