上传文件,因为上传的都是二进制数据,所以在Servlet中就不能直接用request.getParameter();方法进行数据的获取,需要借助第三方jar包对上传的二进制文件进行解析。常用的方式如下:
一:使用SmartUpload.jar
它是一个商业类库,解析request过程中,数据是存放在内存中的,因此速度比较快,但是上传大文件的时候会出现内存溢出。
二:commons-fileupload.jar (Apache commons)、commons-io.jar
UploadFileServlet .java
public class UploadFileServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("请以POST方式访问该URL"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置请求和响应的编码格式 String encoding = getServletContext().getInitParameter("encoding"); req.setCharacterEncoding(encoding); resp.setCharacterEncoding(encoding); resp.setContentType("text/html"); //核心Api FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); //判断是否是muitipart/form-data类型 if(!ServletFileUpload.isMultipartContent(req)) { resp.getWriter().println("表单的enctype属性不是multipart/form-data类型"); } //设置单个文件上传大小 2M fileUpload.setFileSizeMax(2*1024*1024); //设置总上传文件大小(有时候一次性上传多个文件,需要有一个上限,此处为10M) fileUpload.setSizeMax(10*1024*1024); //设置上传监听器[参数为自定义的监听器] fileUpload.setProgressListener(new ListenerUploadProgress()); //解析请求 try { List<FileItem> parseRequest = fileUpload.parseRequest(req); //获取数据 for (FileItem fileItem : parseRequest) { //判断数据类型是不是普通的form表单字段 if(!fileItem.isFormField()) { //上传文件 String fileName = fileItem.getName(); InputStream fileStream = fileItem.getInputStream(); //定义保存的父路径 String parentDir = this.getServletContext().getRealPath("/WEB-INF/upload"); //使用UUID+文件名的方式,避免文件重名 String realFileName = UUID.randomUUID().toString()+"-"+fileName; //创建要保存的文件 File file = new File(parentDir,realFileName); //判断文件夹是否存在 if(!file.getParentFile().exists()) { //创建文件夹[多级文件夹]file.madir是创建单一文件夹 file.getParentFile().mkdirs(); } //创建输出流 OutputStream out = new FileOutputStream(file); //创建字节缓存 byte[] buffer = new byte[1024]; int len = -1; //一次读取1kb(1024byte),返回-1表明读取完毕 while((len = fileStream.read(buffer))!=-1) { //一次写入1kb(1024byte) out.write(buffer,0, len); } //冲刷流资源 out.flush(); //关闭流 out.close(); fileStream.close(); }else { //普通字段 //字段名 String fieldName = fileItem.getFieldName(); //字段值 String fieldValue = fileItem.getString(); System.out.println(fieldName+":"+fieldValue); } } } catch (FileUploadException e) { e.printStackTrace(); } } }
ListenerUploadProgress.java
public class ListenerUploadProgress implements ProgressListener { /** * @param bytesRead 已经读取的字节数 * @param contentLength 文件总长度 * @param items 当前上传的是哪个文件 */ @Override public void update(long bytesRead, long contentLength, int items) { System.out.println(bytesRead); System.out.println(contentLength); System.out.println(items); } //*前端可以根据该信息写一个上传进度条 }