• org.springframework.util.Base64Utils线程安全问题


      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
    没有问题的话,还是采用这种方式吧
     

    附件列表

  • 相关阅读:
    情感日记:离校,漂流他乡
    汉化破解:{smartassembly}使用指南
    金融市场:Open.Yale.course:Financial.Markets.07.Chi_Eng
    【转载】[解决系统服务运行应用程序的权限问题]使用WTSGetActiveConsoleSessionId()的VISTA服务与桌面交互
    【转载】关于sqlserver自增长列的问题
    【转载】如何给IIS添加能访问的文件类型
    【原创】使用反射之后,强制类型转化不成功的问题在哪?
    【转载】网站开发人员应该知道的61件事
    【索引】转载关于DSL、代码生成器使用、依赖注入方式
    【原】使用SoundPlayer播放wav文件时产生杂音如何处理
  • 原文地址:https://www.cnblogs.com/jiangzhengjun/p/10840742.html
Copyright © 2020-2023  润新知