zoukankan      html  css  js  c++  java
  • 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
    没有问题的话,还是采用这种方式吧
     

    附件列表

  • 相关阅读:
    快速排序?
    算法和数据结构?
    渲染一个react?
    移动端兼容适配?
    PWA全称Progressive Web App,即渐进式WEB应用?
    InnoDB一棵B+树可以存放多少行数据?
    移动端首屏优化?
    InnoDB什么时候会锁表?
    数组去重,多种方法?
    如何处理异形屏iphone X?
  • 原文地址:https://www.cnblogs.com/jiangzhengjun/p/10840742.html
Copyright © 2011-2022 走看看