commons-fileupload这东西上传和保存文件很方便,但读取里面的field的值的时候就很麻烦,总是循环一遍并比较名字才能取到值,极其不便,于是不得不做了个实用类,进行封装,用起来好多了,并且可以直接保存文件,我觉得还是挺方便的,共享一下吧。
原先取域的值的时候,代码类似如下:
for (FileItem item : items) { if (item.isFormField()) { fieldName = item.getFieldName(); if (fieldName.equals("email")) { email= item.getString("UTF-8").trim(); } else if (fieldName.equals("username")) { username = item.getString("UTF-8").trim(); }
有一两个field问题不大,但如果有几十个呢,上百个呢?代码就很冗长和乏味了。
用了我写的UploadForm,取值就跟读取普通表单的field一样容易,如:
String email = uploadForm.getStringField("email");
完整代码如下,重要的地方写了注释:
import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.*; import com.liferay.portal.util.PortalUtil; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.lang.StringUtils; import javax.portlet.PortletRequest; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; public class UploadForm { private static Log log = LogFactoryUtil.getLog(UploadForm.class); private HttpServletRequest request; private HashMap<String, Object> fields = new HashMap<String, Object>(); private List<FileItem> oriFileItems = new ArrayList<FileItem>(); public UploadForm(HttpServletRequest request) { this.request = request; init(); } public UploadForm(PortletRequest request) { this(PortalUtil.getHttpServletRequest(request)); } private void init() { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload uploader = new ServletFileUpload(factory); try { List<FileItem> items = uploader.parseRequest(request); for (FileItem item : items) { oriFileItems.add(item); String fieldName = item.getFieldName(); log.debug("field name: " + fieldName); if (item.isFormField()) { String fieldValue = null; try { fieldValue = item.getString("utf-8"); } catch (UnsupportedEncodingException e) { log.error(e); } if (fields.get(fieldName) != null) { Object value = fields.get(fieldName); if (value instanceof List) { ((List) value).add(item.getString()); } else { fields.put(fieldName, ListUtil.fromArray(new String[]{String.valueOf(value), fieldValue})); } } else { try { fields.put(fieldName, item.getString("utf-8")); } catch (UnsupportedEncodingException e) { log.error(e); } } } else { //it's a file if (fields.get(fieldName) != null) { Object value = fields.get(fieldName); if (value instanceof List) { ((List) value).add(item.getString()); } else { fields.put(fieldName, ListUtil.fromArray(new Object[]{value, item})); } } else {//first time checked fields.put(fieldName, item); } } } } catch (FileUploadException e) { log.error(e); } } /** * get the values of form fields * * @param fieldName * @return return "" if nothing is input for non-checkbox or non-radiobutton, * return null if nothing is selected for checkbox or radiobutton */ public String getStringField(String fieldName) { return MapUtil.getString(fields, fieldName); } public long getLongField(String fieldName) { if (StringUtils.isNotEmpty(getStringField(fieldName))) { return Long.parseLong(getStringField(fieldName)); } else { return -1; } } public int getIntField(String fieldName) { if (StringUtils.isNotEmpty(getStringField(fieldName))) { return Integer.parseInt(getStringField(fieldName)); } else { return -1; } } public float getFloatField(String fieldName) { if (StringUtils.isNotEmpty(getStringField(fieldName))) { return Float.parseFloat(getStringField(fieldName)); } else { return -1; } } public double getDoubleField(String fieldName) { if (StringUtils.isNotEmpty(getStringField(fieldName))) { return Double.parseDouble(getStringField(fieldName)); } else { return -1; } } /** * 取多值field的值,如checkbox * @param fieldName * @return */ public String[] getStringFields(String fieldName) { if (!fields.containsKey(fieldName)) { return new String[0]; } Object value = fields.get(fieldName); if (value instanceof List) { List<String> listValue = (List) value; return listValue.toArray(new String[0]); } else { return new String[]{String.valueOf(fields.get(fieldName))}; } } /** * 取多值字段的原始FileItem * @param fieldName * @return */ public FileItem[] getFileItemFields(String fieldName){ if (!fields.containsKey(fieldName)){ return new FileItem[]{}; } if (fields.get(fieldName) instanceof List){ List<FileItem> listField = (List)fields.get(fieldName); return listField.toArray(new FileItem[0]); }else{ return new FileItem[]{((FileItem) fields.get(fieldName))}; } } public Object getField(String fieldName) { return fields.get(fieldName); } /** * 保存文件 * * @param fieldName 表单项的名字 * @param saveName 保存文件名,含扩展名,不含文件夹部分 * @param folder 保存的文件夹 * @return */ public FileWrapper saveFile(String fieldName, String saveName, String folder) { if (fields.get(fieldName) instanceof List){ throw new IllegalArgumentException("Duplicated file selector['"+fieldName+"'] found! Ensure only one exists"); } FileItem fileItem = (FileItem) fields.get(fieldName); if (!FileUtil.exists(folder)) { FileUtil.mkdirs(folder); } String fullPath = folder.replaceAll("\\\\", "/") + "/" + saveName; if (FileUtil.exists(fullPath)) { return null; } else { try { File file = new File(fullPath); fileItem.write(file); FileWrapper rspFile = new FileWrapper(file); rspFile.setOldName(fileItem.getName()); return rspFile; } catch (Exception e) { log.error(e); return null; } } } /** * 用原先的文件名保存文件 * * @param fieldName * @param folder * @return */ public FileWrapper saveFile(String fieldName, String folder) { FileItem fileItem = (FileItem) fields.get(fieldName); return saveFile(fieldName, fileItem.getName(), folder); } /** * 用UUID作为文件名保存文件 * * @param fieldName * @param folder * @return */ public FileWrapper saveFileWithUUID(String fieldName, String folder) { FileItem fileItem = (FileItem) fields.get(fieldName); String oriFileName = fileItem.getName(); String fileName = oriFileName.contains(".") ? UUID.randomUUID().toString() + "." + FileUtil.getExtension(oriFileName) : UUID.randomUUID().toString(); return saveFile(fieldName, fileName, folder); } public FileWrapper saveFileItem(FileItem fileItem, String saveName, String folder) { if (StringUtils.isEmpty(fileItem.getName())){ return null; } if (!FileUtil.exists(folder)) { FileUtil.mkdirs(folder); } String fullPath = folder.replaceAll("\\\\", "/") + "/" + saveName; if (FileUtil.exists(fullPath)) { return null; } else { try { File file = new File(fullPath); fileItem.write(file); FileWrapper rspFile = new FileWrapper(file); rspFile.setOldName(fileItem.getName()); return rspFile; } catch (Exception e) { log.error(e); return null; } } } public FileWrapper saveFileWithUUID(FileItem fileItem, String folder) { String oriFileName = fileItem.getName(); if (StringUtils.isEmpty(oriFileName)){ return null; } String fileName = oriFileName.contains(".") ? UUID.randomUUID().toString() + "." + FileUtil.getExtension(oriFileName) : UUID.randomUUID().toString(); return saveFileItem(fileItem,fileName,folder); } public List<FileWrapper> saveFilesWithUUID(List<FileItem> fileItemList, String folder) { List<FileWrapper> files=new ArrayList<FileWrapper>(); for (FileItem fileItem : fileItemList) { files.add(saveFileWithUUID(fileItem, folder)); } return files; } public List<FileWrapper> saveFilesWithUUID(String fieldName, String folder) { FileItem[] fileItems=getFileItemFields(fieldName); List<FileWrapper> files=new ArrayList<FileWrapper>(); for (FileItem fileItem : fileItems) { files.add(saveFileWithUUID(fileItem, folder)); } return files; } /** * 按名称关键字搜索字段并返回FileItem数组,对于有些field,名字前缀一样,但可能加个不同的序号 * 适合于动态添加的表单域 * @param fieldNameKeyword * @return */ public FileItem[] getFileItemArrByKeyword(String fieldNameKeyword){ List<FileItem> fileItemList=new ArrayList<FileItem>(); for (FileItem fileItem : oriFileItems) { if (fileItem.getFieldName().toLowerCase().contains(fieldNameKeyword.toLowerCase())){ fileItemList.add(fileItem); } } return getFileItemListByKeyword(fieldNameKeyword).toArray(new FileItem[0]); } public List<FileItem> getFileItemListByKeyword(String fieldNameKeyword){ return getFileItemListByKeyword(fieldNameKeyword,true); } public List<FileItem> getFileItemListByKeyword(String fieldNameKeyword, boolean isFile){ List<FileItem> fileItemList=new ArrayList<FileItem>(); for (FileItem fileItem : oriFileItems) { if (fileItem.getFieldName().toLowerCase().contains(fieldNameKeyword.toLowerCase())){ if (isFile){ if (!fileItem.isFormField() && fileItem.getSize()>0){ fileItemList.add(fileItem); } }else{ fileItemList.add(fileItem); } } } return fileItemList; } public String[] getStringArrByKeyword(String fieldNameKeyword){ return getStringListByKeyword(fieldNameKeyword).toArray(new String[0]); } public List<String> getStringListByKeyword(String fieldNameKeyword){ List<String> strItemList=new ArrayList<String>(); for (FileItem fileItem : oriFileItems) { if (fileItem.getFieldName().toLowerCase().contains(fieldNameKeyword.toLowerCase())){ try { strItemList.add(fileItem.getString("UTF-8")); } catch (UnsupportedEncodingException e) { log.error(e); } } } return strItemList; } public long getFileByteSize(String fieldName) { FileItem fileItem = (FileItem) fields.get(fieldName); return fileItem.getSize(); } /** * 取得文件大小,单位KB * @param fieldName * @return */ public float getFileKBSize(String fieldName) { return getFileByteSize(fieldName) / 1024.0f; } public double getFileMBSize(String fieldName) { return getFileByteSize(fieldName) / 1024.0 / 1024; } public boolean exist(String fieldName) { return fields.containsKey(fieldName); } }
用到的文件包装器,可以返回上传文件的原始名字,url编码后的名字等等,便于下载用到:
import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.FileUtil; import java.io.File; import java.io.UnsupportedEncodingException; /** * 文件的实用类,含有一些实用的方法 */ public class FileWrapper { private static Log log = LogFactoryUtil.getLog(FileWrapper.class); private File file; private String oldName; public FileWrapper(File file) { this.file = file; } public String getFileName(){ return file.getName(); } /** * 获得文件被保存的路径,不含文件名 * @return */ public String getFolderPath(){ return FileUtil.getPath(file.getAbsolutePath()); } /** * 将文件名转码成url中用的编码 * @return */ public String getUrlEncodingName(){ try { return java.net.URLEncoder.encode(oldName, "UTF-8"); } catch (UnsupportedEncodingException e) { log.error(e); return ""; } } /** * 获得文件原始名 * @return */ public String getOldName() { return oldName; } public void setOldName(String oldName) { if (oldName.contains("\\") || oldName.contains("/")){ oldName = oldName.replaceAll("\\\\","/"); oldName = oldName.substring(oldName.lastIndexOf("/")); this.oldName = oldName; }else{ this.oldName = oldName; } } public String getExtName(){ return FileUtil.getExtension(file.getAbsolutePath()); } public String getFullPath(){ return file.getAbsolutePath(); } }
调用示例:
UploadForm uploadForm=new UploadForm(request); String zip_code = uploadForm.getStringField("zip_code"); List<String> provinces = uploadForm.getStringListByKeyword("province");//省份字段是在页面动态添加的 List<FileWrapper> certFileList = uploadForm.saveFilesWithUUID(uploadForm.getFileItemListByKeyword("certFile"), "d:/upload");//上传文件的保存
通过这种封装,以后使用commons-fileupload就不再是一件头疼的事了。不过,代码中用到了一少部分liferay的一些实用类,可以根据需要很容易地自己写或其它开源类库替换