zoukankan      html  css  js  c++  java
  • Struts文件上传allowedTypes问题,烦人的“允许上传的文件类型”

     

    Struts的文件上传问题,相信很多人都会使用allowedTypes参数来配置允许上传的文件类型,如下。

    MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
    每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
    因为jpg的大类别是图像,所以是image,具体种类是jpg。

    1. <param name="allowedTypes">  
    2.     image/png,image/bmp,image/jpg  
    3. </param>  

    但是,用过这个参数的人都知道,allowedTypes是“文件类型”, 而不是“文件后缀名”,文件类型与文件后缀名有什么区别呢?

    就如后缀名为bmp的图片的文件类型为image/bmp,后缀名为xls的Excel文件类型为application/vnd.ms-excel等等....

    这各种各样的”文件类型“,让人烦不胜烦。。。。

    猜想是否可以根据后缀名来过滤允许上次的文件,Struts如此红火的框架应该能想到这点。

    于是便打开Struts文件上次的拦截器org.apache.struts2.interceptor.FileUploadInterceptor一看,发现如下代码:

    1. protected Set<String> allowedTypesSet = Collections.emptySet();  
    2. protected Set<String> allowedExtensionsSet = Collections.emptySet();  


    看到一个allowedTypesSet和一个allowedExtensionsSet,很容易想到,前者是用于存放参数allowedTypes的,

    而后者呢,自然是用于存放参数allowedExtensions的,extension翻为:延长、扩展...

    所以,我们可以大胆的猜想,allowedExtensions参数就是用于配置”允许上传的文件后缀名“。

    再来看看FileUploadInterceptor里的一个方法acceptFile(),此方法用于根据当前配置,检查该文件是否允许被上传

    1. protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale) {  
    2.     boolean fileIsAcceptable = false;  
    3.   
    4.     // If it's null the upload failed  
    5.     if (file == null) {  
    6.         String errMsg = getTextMessage(action, "struts.messages.error.uploading", new Object[]{inputName}, locale);  
    7.         if (validation != null) {  
    8.             validation.addFieldError(inputName, errMsg);  
    9.         }  
    10.   
    11.         LOG.warn(errMsg);  
    12.     } else if (maximumSize != null && maximumSize < file.length()) {  
    13.         String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new Object[]{inputName, filename, file.getName(), "" + file.length()}, locale);  
    14.         if (validation != null) {  
    15.             validation.addFieldError(inputName, errMsg);  
    16.         }  
    17.   
    18.         LOG.warn(errMsg);  
    19.     } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) {  
    20.         String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale);  
    21.         if (validation != null) {  
    22.             validation.addFieldError(inputName, errMsg);  
    23.         }  
    24.   
    25.         LOG.warn(errMsg);  
    26.     } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) {  
    27.         String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale);  
    28.         if (validation != null) {  
    29.             validation.addFieldError(inputName, errMsg);  
    30.         }  
    31.   
    32.         LOG.warn(errMsg);  
    33.     } else {  
    34.         fileIsAcceptable = true;  
    35.     }  
    36.   
    37.     return fileIsAcceptable;  
    38. }  


    别的先不管,先看看到第2,3个else if节点,分别是利用了allowedTypesSet和allowedExtensionsSet,如下

    1. else if (allowedTypesSet不为空 && allowedTypesSet不包含该文件的类型) {  
    2.   
    3. // 添加错误信息....  
    4.   
    5. else if (allowedExtensionsSet不为空 && allowedExtensionsSet不包含该文件的后缀名) {  
    6.   
    7. // 添加错误信息  
    8.   
    9. }  

    从上面的代码中可以看出,如果我们要利用allowedExtensions参数来控制上传文件的后缀名,则不能配置allowedTypes参数。

    否则,如果allowedTypes参数有配置,那么allowedExtensions参数将不会再起效。

    总结

    使用Struts文件上次功能,我们可以使用”文件类型“和”文件后缀名“两者中的一个来控制上传文件的类型/后缀名。但 是,allowedTypes的优先级别高于allowedExtensions,如果配置了allowedTypes则 allowedExtensions将不再起效。最后附上allowedExtensions的一个简单配置:

      1. <!-- 允许后缀名为png,bmp,jpg,doc,xls的文件上传 -->     
      2. <param name="allowedExtensions">  
      3.     png,bmp,jpg,doc,xls  
      4. </param
  • 相关阅读:
    HTTP请求中的GET-POST方式
    拦截器与过滤器的不同点
    SQL练习题(一)
    Maven聚合工程安装时排除掉不参与本次安装的子工程
    codeforce 796C
    [CF1216E] Numerical Sequence hard version
    【floyd+矩阵乘法】POJ 3613 Cow Relays
    BZOJ 3573米特运输
    Poj 3977 Subset
    【树形dp】Bzoj 1040骑士
  • 原文地址:https://www.cnblogs.com/bb3q/p/4547875.html
Copyright © 2011-2022 走看看