把Form表单是的enctype="multipart/form-data"是基于流的,只能获取一次,重复获取将为空,当上传文件的input控件与hidden的input字段混合时,直接用request.getParameter一般是不行的.
下面的代码进行同时表单参数获取和文件上传:
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.fileupload.servlet.ServletRequestContext; ... Map<String, Vector<String>> getFieldMap( HttpServletRequest request) throws UnsupportedEncodingException { Map<String, Vector<String>> fieldsMap; fieldsMap = (Map<String, Vector<String>>) request .getAttribute(ServletFileUpload.MULTIPART_FORM_DATA); if (fieldsMap == null) { fieldsMap = new HashMap<String, Vector<String>>(); request.setAttribute(ServletFileUpload.MULTIPART_FORM_DATA, fieldsMap); } else { return fieldsMap; } ServletFileUpload fu = new ServletFileUpload(new DiskFileItemFactory()); List<FileItem> li = null; try { li = fu.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); } int m = 0; if (li != null) { Iterator<FileItem> iter = li.iterator(); while (iter.hasNext()) { FileItem fi = (FileItem) iter.next(); if (fi.isFormField()) { Vector<String> vec = new Vector<String>(); String fieldName = fi.getFieldName(); // 这里取得字段名称 // 如果已经存在此字段信息(多选列表或多个同名的隐藏域等) if (fieldsMap.get(fieldName) != null) { vec = (Vector<String>) fieldsMap.get(fieldName); vec.add(fi.getString(request.getCharacterEncoding())); } // 第一次取到这个名的字段 else { // logger.info("name:" + fieldName + " value: " // + fi.getString(request.getCharacterEncoding())); vec.add(fi.getString(request.getCharacterEncoding())); fieldsMap.put(fieldName, vec); } } else { List<String> fileNames = (List<String>) request .getAttribute(UPLOADEDFILENAME_ATTRIBUTE); if (fileNames == null) { fileNames = new ArrayList<String>(); request.setAttribute(UPLOADEDFILENAME_ATTRIBUTE, fileNames); } String storePath = request.getSession().getServletContext() .getRealPath(UPLOADEDFILEPATH); try { if (fi.getSize() > 0) { //这里而要对文件重全名, 可能从之前的filename取得扩展名,并白名单过滤 fi.write(new File("somefilename"+m++)); // 写文件到服务器. } } catch (Exception e) { e.printStackTrace(); } } } } return fieldsMap; }
这里用的是apache的common-fileupload模块.
如果您使用maven构建, 需要在pom.xml里添加:
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2</version> </dependency>