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

    附件列表

  • 相关阅读:
    Android进阶之关闭所有activty
    弹出窗口插件欣赏
    关于之前放在google 的资源不能下载的解决方案
    图片垂直居中的使用技巧
    关于采用业务用例视图来展示、归纳、整理业务用例的三点指导原则
    操作系统引导的那点事
    可视化拾色器
    AE中删除属性字段
    AE中添加属性字段
    vs2005c#中用户组件在工具箱中不能自动出现的解决办法
  • 原文地址:https://www.cnblogs.com/jiangzhengjun/p/10840742.html
Copyright © 2011-2022 走看看