1 文件的上传
1.1文件上传的原理
文件上传其实和提交表单中的其他数据是一样的。只不过其他的数据都是以文本的形式提交的。文件是以二进制流的形式提交的。
表单的提交其实也是以流的形式将数据发送到服务器端,在服务器端对流进行处理得到数据。
将表单修改为以二进制流的形式提交,然后在后端获取流中数据观察。
案例:
后台处理:
创建一个UpLoadTestServlet
public class UpLoadTestServlet extends HttpServlet { private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过request获取一个输入流,这个输入流中的数据就是客户端提交的数据 ServletInputStream inputStream = request.getInputStream(); //从流中读取数据 byte[] buff = new byte[1024]; int len = -1; while((len=inputStream.read(buff))!=-1) { String str = new String(buff,0,len); System.out.print(str); } }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
|
上传文件得到的结果是:
1.2 commons-fileupload实现文件上传
[1]了解
commons-fileupload是一个上传文件的组件。是apache下的一个开源的项目。
[2]使用
commons-fileupload依赖于commons-io ,commons-io也是apache的一个开源项目。
首先下载两个jar文件:
下载:commons-fileupload
http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi
下载commons-io:
http://commons.apache.org/proper/commons-io/download_io.cgi
下载完成:
解压,找到对应的jar文件,将jar文件添加到项目中:
[3]在servlet中使用fileupload实现文件的上传处理
S1:DiskFileItemFactory中的API
创建ServletFileUpload对象
ServletFileUpload fileUpload = new ServletFileUpload(factory);
API:
此对象可以通过parseRequest解析输入流中的数据。
FileItem的API:
判断是否是普通的表单域,是就返回true,文件域就返回false
获取文件域中文件的名称:
获取域中的名称:
获取表单域的值,如果是文件域返回null
将临时文件写入目标文件
package com.igeek.servlet;
public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建DiskFileItemFactory 对象 DiskFileItemFactory factory = new DiskFileItemFactory(); //设置缓存大小 factory.setSizeThreshold(2048); //设置临时仓库(临时目录) factory.setRepository(new File("temp")); //创建ServletFileUpload对象 ServletFileUpload fileUpload = new ServletFileUpload(factory); // //判断是否解析到数据 if(!fileUpload.isMultipartContent(request)) { return; } try { //解析request得到请求数据 List<FileItem> items = fileUpload.parseRequest(request); //遍历items for (FileItem fileItem : items) { if(fileItem.isFormField()) { //普通表单域 //获取表单域的名称 String fieldName = fileItem.getFieldName(); //获取表单域的值 String value = fileItem.getString(); System.out.println("普通表单域:"+fieldName+"-"+value); }else { //文件域 //获取文件名 String fileName = fileItem.getName(); System.out.println("文件名:"+fileName); //将文件写入到指定的目标文件 fileItem.write(new File("D:\\upload\\"+fileName)); } } } catch (Exception e) { e.printStackTrace(); } } }
|
ServletFileUpload的api的补充
设置一次性上传文件的最大大小:
设置上传文件的单个文件的最大大小:
设置字符集
1.3获取服务的路径
需求是将上传的文件存在当前项目的upload文件件中:
存储在磁盘上的文件的物理名称自动生成。
获取服务器的绝对路径:
获取服务器的根目录的绝对路径:
2 文件下载
[1]直接让超链接指向服务器中的要下载的资源,即可下载。
要下载的文件如果浏览器是可以解释展示的,会直接展示在浏览器中。否则就下载。
[2]使用servlet响应下载请求
案例:添加DownloadServlet
public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取要下载的文件名 String filename = request.getParameter("filename"); //获取资源文件的目录 String path = this.getServletContext().getRealPath("resource/"); //要下载的文件对象 File file = new File(path, filename); //创建输入流读取文件 FileInputStream in = new FileInputStream(file); //下载文件的相关配置 //设置文长度 response.setContentLengthLong(file.length()); //设置文件的内容类型 response.setContentType("image/jpeg"); //设置文件的描述 (设置问价以附件的形式下载以及文件名设置) response.setHeader("content-disposition", "attachment;filename="+filename); //获取输出流写出文件 ServletOutputStream out = response.getOutputStream(); //文件拷贝了 byte [] buff = new byte[1024]; int len = -1; while((len = in.read(buff))!=-1) { out.write(buff,0,len); out.flush(); } out.close(); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
|
请求: