Struts的文件上傳問題,相信很多人都會使用allowedTypes參數來配置允許上傳的文件類型,如下。
- <param name="allowedTypes">
- image/png,image/bmp,image/jpg
- </param>
但是,用過這個參數的人都知道,allowedTypes是“文件類型”, 而不是“文件後綴名”,文件類型與文件後綴名有什麼區別呢?
就如後綴名爲bmp的圖片的文件類型爲image/bmp,後綴名爲xls的Excel文件類型爲application/vnd.ms-excel等等....
這各種各樣的”文件類型“,讓人煩不勝煩。。。。
猜想是否可以根據後綴名來過濾允許上次的文件,Struts如此紅火的框架應該能想到這點。
於是便打開Struts文件上次的攔截器org.apache.struts2.interceptor.FileUploadInterceptor一看,發現如下代碼:
- protected Set<String> allowedTypesSet = Collections.emptySet();
- protected Set<String> allowedExtensionsSet = Collections.emptySet();
看到一個allowedTypesSet和一個allowedExtensionsSet,很容易想到,前者是用於存放參數allowedTypes的,
而後者呢,自然是用於存放參數allowedExtensions的,extension翻爲:延長、擴展...
所以,我們可以大膽的猜想,allowedExtensions參數就是用於配置”允許上傳的文件後綴名“。
再來看看FileUploadInterceptor裏的一個方法acceptFile(),此方法用於根據當前配置,檢查該文件是否允許被上傳
- protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale) {
- boolean fileIsAcceptable = false;
- // If it's null the upload failed
- if (file == null) {
- String errMsg = getTextMessage(action, "struts.messages.error.uploading", new Object[]{inputName}, locale);
- if (validation != null) {
- validation.addFieldError(inputName, errMsg);
- }
- LOG.warn(errMsg);
- } else if (maximumSize != null && maximumSize < file.length()) {
- String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new Object[]{inputName, filename, file.getName(), "" + file.length()}, locale);
- if (validation != null) {
- validation.addFieldError(inputName, errMsg);
- }
- LOG.warn(errMsg);
- } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) {
- String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale);
- if (validation != null) {
- validation.addFieldError(inputName, errMsg);
- }
- LOG.warn(errMsg);
- } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) {
- String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale);
- if (validation != null) {
- validation.addFieldError(inputName, errMsg);
- }
- LOG.warn(errMsg);
- } else {
- fileIsAcceptable = true;
- }
- return fileIsAcceptable;
- }
別的先不管,先看看到第2,3個else if節點,分別是利用了allowedTypesSet和allowedExtensionsSet,如下
- } else if (allowedTypesSet不爲空 && allowedTypesSet不包含該文件的類型) {
- // 添加錯誤信息....
- } else if (allowedExtensionsSet不爲空 && allowedExtensionsSet不包含該文件的後綴名) {
- // 添加錯誤信息
- }
從上面的代碼中可以看出,如果我們要利用allowedExtensions參數來控制上傳文件的後綴名,則不能配置allowedTypes參數。
否則,如果allowedTypes參數有配置,那麼allowedExtensions參數將不會再起效。
總結
使用Struts文件上次功能,我們可以使用”文件類型“和”文件後綴名“兩者中的一個來控制上傳文件的類型/後綴名。但是,allowedTypes的優先級別高於allowedExtensions,如果配置了allowedTypes則allowedExtensions將不再起效。最後附上allowedExtensions的一個簡單配置:
- <!-- 允許後綴名爲png,bmp,jpg,doc,xls的文件上傳 -->
- <param name="allowedExtensions">
- png,bmp,jpg,doc,xls
- </param>