简单的文件上传的下载(动态web项目)
1、在页面中定义一个form表单,如下:
1 <!-- 文件上传 --> 2 <form action="${pageContext.request.contextPath}/FileServlet?oper=fileUpload" method="post" 3 enctype="multipart/form-data"> 4 用户名:<input type="text" name="username"><br><!--普通表单项,没有用--> 5 <input type="file" name="file"><br> 6 <input type="file" name="file"><br> 7 <input type="submit" value="上传"> 8 </form> 9 <!-- 文件下载 --> 10 <a href="${pageContext.request.contextPath}/RegisterServlet?oper=fileDownload">下载</a>
注意:
向服务器上传一个文件时,表单要使用post请求。
表单的默认属性enctype="application/x-www-form-urlencoded",这个属性的意思是请求体中的内容将会使用URL编码
上传文件的表单enctype需要设置为 multipart/form-data
multipart/form-data表示的是表单是一个多部件的表单
如果类型设置为它,则我们的每一个表单项都会作为一个单独的部件发送给服务器。
多个部件之间使用类似 -----------------------------7df2d08c0892 分割符来分开
当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。
2、在doPost方法中,(需要导入两个jar包:commons-fileupload-1.3.1.jar和commons-io-2.4.jar)
文件上传和下载的jar包(百度云) 密码:ftbi
1 //使用简单的反射将参数oper映射成函数对象 2 protected void doGet(HttpServletRequest request, HttpServletResponse response) 3 throws ServletException, IOException { 4 request.setCharacterEncoding("utf-8"); 5 response.setContentType("text/html;charset=utf-8"); 6 String methodName = request.getParameter("oper"); 7 Class cla = this.getClass(); 8 try { 9 Method method = cla.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); 10 method.setAccessible(true); 11 method.invoke(this, request, response); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 } 16 protected void doPost(HttpServletRequest request, HttpServletResponse response) 17 throws ServletException, IOException { 18 doGet(request, response);//doPost()中调用doGet()方法 19 } 20 protected void fileUpload(HttpServletRequest request, HttpServletResponse response) throws Exception { 21 // 1、创建工厂类 22 DiskFileItemFactory factory = new DiskFileItemFactory(); 23 // 2、创建ServletFileUpload对象,通过这个对象完成文件上传功能 24 ServletFileUpload fileUpload = new ServletFileUpload(factory); 25 fileUpload.setFileSizeMax(150*1024);//对单个文件大小做限制 26 fileUpload.setSizeMax(2*1024*1024);//对总文件大小做限制 27 ServletContext servletContext = request.getServletContext();//获取servletContext对象 28 String realPath=servletContext.getRealPath("/upload");//获取服务器的根目录(存储) 29 File file=new File(realPath); 30 if(!file.exists()){//如果目录不存在,则创建该目录 31 file.mkdirs(); 32 } 33 try { 34 // 3、用这个fileUpload对象解析request请求 35 List<FileItem> fileList = fileUpload.parseRequest(request); 36 for (FileItem item : fileList) { 37 // 如果是普通表单项 38 if (item.isFormField()) { 39 String name = item.getFieldName();// 获取name属性 40 String value = item.getString("utf8");// 获取value值 41 // System.out.println(name + ":" + value); 42 } else {// 如果上传的是文件 43 // String contentType = item.getContentType();// 获取文件的类型 44 // String fieldName = item.getFieldName();// 获取文件域的name属性 45 long size = item.getSize();// 获取文件的大小 46 if(size==0){//如果没有上传文件,则继续往下执行 47 continue; 48 } 49 String name = item.getName();// 获取文件的名字 50 //在IE浏览器中获取到的是文件名的全路径,需要通过截取字符串获得文件的名字 51 //谷歌和火狐中获取的只是文件的名字,不需要截取 52 if(name.contains("\\")){ 53 name=name.substring(name.lastIndexOf("\\")+1); 54 } 55 //为了上传同名文件时不被覆盖,需要对文件的名字进行加前缀处理 56 String prefix = UUID.randomUUID().toString();//UUID:机器码+时间戳 57 prefix = prefix.replace("-", ""); 58 String fileName = prefix+"_"+name; 59 //将文件写到服务器 60 item.write(new File(realPath+"//"+fileName)); 61 } 62 } 63 }catch(FileSizeLimitExceededException e) { 64 System.out.println("文件大小不能超过150K"); 65 }catch(SizeLimitExceededException e) { 66 System.out.println("文件总大小不能超过2M"); 67 }catch (FileUploadException e) { 68 e.printStackTrace(); 69 } 70 } 71 protected void fileDownload(HttpServletRequest request, HttpServletResponse response) 72 throws SQLException, ServletException, IOException { 73 ServletContext servletContext = request.getServletContext(); 74 String fileName = "海若有因.mp3"; 75 String path = servletContext.getRealPath("/WEB-INF/res/"+fileName); 76 File file = new File(path); 77 //1.创建输入流 78 InputStream in = new FileInputStream(file); 79 //获取文件的MIME类型 80 String type = servletContext.getMimeType(path); 81 //设置响应头---文件类型 Content-Type为文件的MIME类型 82 response.setContentType(type); 83 //解决文件名中文乱码的问题 84 fileName = new String(fileName.getBytes("gbk"),"iso8859-1");//这是一种不太讲理的方式 85 //设置响应头---下载文件的信息 Content-Disposition为attachment; filename=文件名 86 //Content-Disposition告诉浏览器如何处理文件 87 //attachment 告诉浏览器这个文件是一个附件的形式发给你的,需要你做下载的操作 88 //filename 告诉浏览器下载文件的名字 89 response.setHeader("Content-Disposition","attachment;filename="+fileName); 90 //从response获取输出流,不需要手动关闭 91 ServletOutputStream out=response.getOutputStream(); 92 //将输入流写到输出流 93 IOUtils.copy(in, out); 94 in.close();//关闭输入流 95 }
函数反射参见:用简单的反射优化代码(动态web项目)
不想学好基础的程序员不是好的程序员。