input上传文件时的注意事项
2013-09-10 12:56 阿昌wining 阅读(711) 评论(0) 收藏 举报近几天公司要求开发一个文件上传并入库的功能,功能不难实现,网上代码随处可见!由于要求文件格式为Excel文档,故只能通过file控件上传文件, 并通过ServletFileUpload对象进行解析上传的文件信息,进而获取Excel中的数据信息,具体实现如下: jsp页面: <form action="ImportExcelServlet" method="post" enctype="multipart/form-data"> <input type="file" /> <input type="submit" value="导入" /> </form> java代码: 1、servlet实现 import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
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;
/** * Servlet implementation class ImportExcelServlet */ public class ImportExcelServlet extends HttpServlet { private static final long serialVersionUID = 1L;
// 缓冲区域 File tempPathFile; // 默认路径 String uploadTo = "D:\\"; // 支持的文件类型 String[] errorType = { ".xls" }; // 格式化日期 SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
/** * @see HttpServlet#HttpServlet() */ public ImportExcelServlet() { super(); // TODO Auto-generated constructor stub }
/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }
/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); // 取得服务器真实路径 // uploadTo = req.getSession().getServletContext().getRealPath("\\") // +"upload\\"; // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置缓冲区大小,这里是4kb //factory.setSizeThreshold(4096); // 设置缓冲区目录 //factory.setRepository(tempPathFile); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Set overall request size constraint // 设置最大文件尺寸,这里是4MB upload.setSizeMax(4 * 1024 * 1024); // 开始读取上传信息 List fileItems = new ArrayList(); try { fileItems = upload.parseRequest(request); } catch (FileUploadException e1) { e1.printStackTrace(); } // 依次处理每个上传的文件 Iterator iter = fileItems.iterator(); System.out.println("fileItems的大小是" + fileItems.size()); // 正则匹配,过滤路径取文件名 String regExp = ".+\\\\(.+)$"; Pattern p = Pattern.compile(regExp); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); // 忽略其他不是文件域的所有表单信息 System.out.println("正在处理" + item.getFieldName()); if (!item.isFormField()) { String name = item.getName(); long size = item.getSize(); if ((name == null || name.equals("")) && size == 0) continue; Matcher m = p.matcher(name); boolean result = m.find(); if (result) { boolean flag = false; for (int temp = 0; temp < errorType.length; temp++) { if (m.group(1).endsWith(errorType[temp])) { flag = true; } } if (!flag) { System.out.println("上传了不支持的文件类型"); throw new IOException(name + ": wrong type"); } try { String fileName = uploadTo + format.format(new Date()) + m.group(1).substring(m.group(1).indexOf(".")); item.write(new File(fileName)); // 调用ReadExcel类进行读出excel // ReadExcel.readExcel(fileName, response.getWriter()); System.out.println(name + "\t\t" + size); } catch (Exception e) { e.printStackTrace(); } } } else { // 这里添加对不是上传文件表单项的处理 System.out.println("这是一个表单项"); } }
}
2、controller实现(dorado项目中) import java.util.ArrayList; import java.util.List; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import jxl.Sheet; import jxl.Workbook; import jxl.read.biff.BiffException; import jxl.read.biff.File; import jxl.Cell;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.log4j.Logger; import com.bstek.dorado.action.Action; import com.bstek.dorado.action.Controller; import com.bstek.dorado.action.mapping.ActionForward;
/** * 投保单信息导入控制器 * @author yueweinan * */ public class PolicyInfoImportController extends Controller { private Logger logger = Logger.getLogger("PolicyInfoImportController"); /** * 允许上传文件的扩展名 */ private static String[] fileNameExtension = { ".xls" }; /** * 允许整个request的大小,默认为1MB */ private static long sizeMax = 1024 * 1024 * 1024; /** * 允许单个文件的最大上传大小,默认为1MB */ private static long fileSizeMax = 1024 * 1024 * 1024; @SuppressWarnings("unchecked") public void doUpload(Action action, HttpServletRequest request, HttpServletResponse response) throws Exception { request.setCharacterEncoding("utf-8"); /*BufferedReader read = request.getReader(); String line = read.readLine(); while (line != null) { System.out.println(line); line = read.readLine(); }*/ /*InputStream inputStream = request.getInputStream(); Workbook workBook = Workbook.getWorkbook(inputStream);*/ if (ServletFileUpload.isMultipartContent(request)) { try { validateSize(request.getContentLength()); // InputStream stream = request.getInputStream(); // // Workbook wookBook = Workbook.getWorkbook(stream); ServletFileUpload fileupload = new ServletFileUpload( new DiskFileItemFactory()); fileupload.setSizeMax(sizeMax); fileupload.setFileSizeMax(fileSizeMax); fileupload.setHeaderEncoding("UTF-8"); List<FileItem> list = fileupload.parseRequest(request); //List<PolicyExecelVo> parseResult = new ArrayList<PolicyExecelVo>(); //1.解析execel if (list != null) { //lis的size为1 for (int i=0; i<list.size(); i++) { FileItem item = list.get(i); InputStream sm = item.getInputStream(); // //parseResult = new PolicyParser().ParseExecel(sm); } } //2.装入缓存 String batchNo = ""; /*if (parseResult!= null && parseResult.size()>0) { batchNo = BatchNoGenerater.generatNo(); PolicyImportCache.push(batchNo, parseResult); }*/ //3.返回对应的导入批次号到页面 request.setAttribute("isUploadSucc", "true"); // request.setAttribute("batchNO", batchNo); } catch (Exception e) { request.setAttribute("isUploadSucc", "false"); throw new Exception(e.getMessage()); } //return action.findForward("success"); } request.setAttribute("isUploadSucc", "true"); request.setAttribute("batchNO", "wangchangli"); //return null; } private void validateFileName(String fileName) { for (String allow : fileNameExtension) { if (!fileName.endsWith(allow)) { /*throw new BusinessException("“" + fileName.substring(fileName.lastIndexOf("\\") + 1) + "”为不允许上传的文件类型!");*/ } } }
private void validateSize(long size) { if (size > sizeMax) { /*throw new BusinessException("文件大小超过上限[" + sizeMax / 1024 / 1024 + "MB]");*/ } } }
当前本人使用的vmware虚拟机桌面进行开发的,eclipse开发环境,tomcat 6.0
简单吧;但是看似简单的功能确出现了很奇怪的问题,无论是方法1,还是方法2在List<FileItem> list = fileupload.parseRequest(request); 的时候,list的size确始终为0;去网上查也没有确切的解决方案。问同事,请教高手都感觉很奇怪;不确信的少年可以把代码拷贝过去试一把;
查找原因:
起初,总是以为List<FileItem> list = fileupload.parseRequest(request);获取FileItem时的代码出现问题,经过查看源代码,并多次debug 发现,解析request的代码没有问题,而是request中没有存在相应的item信息,然后就转向配置文件和jsp页面进行测试; 后来经过反复测试,并加上技术老大帮助下;终于找到原因:原来在解析request对象的时候,input控件必须定义name属性,只有存在name属性的 input控件才能通过fileupload.parseRequest()方法获取对应的FileItem对象信息;尼玛,真奇葩,费了九牛二虎之力终于解决了此问题。希望以后 对大家有所帮助;
另外,本人对request的页面提交机制不是很了解,如果哪位大侠能够给出相关的解释。将感激万分!!!!!!!!!!!!!!
浙公网安备 33010602011771号