Skip to content

一 文件上传

将文件上传至服务器

1 准备工作

1)表单的提交方式为post

2)表单的enctype属性值设置为 enctype=”multipart/form-data”

3)input的type="file"

html
<form action=""  method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
</form>

注:enctype 属性表示在请求发送到服务器之前应该如何对表单数据进行编码。

enctype属性值描述:

application/x-www-form-urlencoded在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)
multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值
text/plain空格转换为 "+" 加号,但不对特殊字符编码

2 通过request.getInputStream获取上传数据 (了解)

java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //无法获取普通表单控件的数据
    String name = request.getParameter("name");
    System.out.println(name);//null
    
    ServletInputStream inputStream = request.getInputStream();
    
    byte[] buff = new byte[1024];
    
    int len = inputStream.read(buff);
    
    String str = new String(buff, 0, len);
    
    System.out.println(str);
    
	}

输出内容:

http
------WebKitFormBoundarywz6ROLypARWgS8d5
Content-Disposition: form-data; name="file"; filename="haha.txt"
Content-Type: text/plain

asfasjflsadfj
asdfasjflasjdf
asfjasljfasdlkf
safjaslfdjlsfj
------WebKitFormBoundarywz6ROLypARWgS8d5--

3通过fileupload组件进行上传

FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下的文件上传功能

3.1 DiskFileItemFactory

核心类,是创建 FileItem 对象的工厂

主要方法:

public DiskFileItemFactory(int sizeThreshold,File repository)构造函数
void setSizeThreshold(int sizeThreshold)设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件。单位字节
void setRepository(java.io.File repository)指定临时文件目录

3.2 ServletFileUpload

负责处理上传的文件数据,并将表单中每个输入项封装成一个 FileItem 对象中

常用方法有:

boolean isMultipartContent(HttpServletRequest request)判断上传表单是否为multipart/form-data类型
List parseRequest(HttpServletRequest request)解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。
setFileSizeMax(long fileSizeMax)设置上传文件的最大值
setSizeMax(long sizeMax)设置上传文件总量的最大值
setHeaderEncoding(String encoding)设置编码格式
setProgressListener(ProgressListener pListener)设置监听

3.3 基本操作

3.3.1 导入相关jar文件

commons-fileupload-1.3.3.jar

commons-io-1.4.jar

3.3.2 执行步骤

1) 创建DiskFileItemFactory对象

FileItemFactory factory = new DiskFileItemFactory();

2) 使用DiskFileItemFactory 对象创建ServletFileUpload对象

ServletFileUpload upload = new ServletFileUpload(factory);

3) 判断表单是否是multipart/form-data类型

ServletFileUpload.isMultipartContent(request)

4)调用parseRequest方法解析request对象,获取保存所有上传内容(FileItem对象)的List对象

5)对list进行迭代,调用其isFormField方法判断是否是普通控件。

6)设置存放文件的路径,保存文件

3.3.3 代码演示

java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    
    //创建文件上传的工厂类对象
    FileItemFactory factory = new DiskFileItemFactory();
    //根据工厂类对象创建ServletFileUpload对象
    ServletFileUpload upload = new ServletFileUpload(factory);
    
    //解决文件名的中文乱码问题
    upload.setHeaderEncoding("utf-8");
    
    //判断表单的类型是否是multpart/form-data
    if(ServletFileUpload.isMultipartContent(request)){
        
        try {
            //将请求参数转换为FileItem对象的集合
            List<FileItem> items = (List<FileItem>)upload.parseRequest(request);
            for (FileItem fileItem : items) {
                //判断是否是普通的表单控件数据
                if(fileItem.isFormField()){
                    //得到表单中name属性的值
                    System.out.println(fileItem.getFieldName());
                    //得到表单参数的值
                    //指定编码方式,解决提交数据的中文乱码
                    System.out.println(fileItem.getString("utf-8"));
                }else{
                    System.out.println(fileItem.getFieldName());
                    //得到文件名
                    System.out.println(fileItem.getName());
                    
                    String path = "D:/upload";
                    File dir = new File(path);
                    //如果文件夹不存在,创建
                    if(!dir.exists()){
                        dir.mkdir();
                    }
                    String name = fileItem.getName();
                    
                    Date date = new Date();
                    long time = date.getTime();
                    //得到文件的名称和后缀
                    String fileName = name.substring(0, name.lastIndexOf("."));
                    String ext = name.substring(name.lastIndexOf(".") + 1);
                    name = fileName + "_" + time + "." + ext;
                    //创建上传文件的File对象
                    File file = new File(path, name);
                    //保存文件
                    fileItem.write(file);
                    //删除临时文件
                    fileItem.delete();
                }
            }
            
            
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
		}

二 文件下载

1 通过超链接

下载

2 通过代码方式

本质上是通过流进行文件的拷贝,由于要下载的文件可以是任何类型,所以需要通过字节流进行处理

2.1 主要步骤

1)获取要下载的文件的输入流

2)设置响应头的Content-Disposition的值

​ response.setHeader("Content-Disposition","attachment;filename=" + fileName);

表示将请求所得的内容存为一个文件的时候提供一个默认的文件名

3)通过response得到输出流

4)通过IO流进行文件的拷贝

5)关闭流

2.2 代码演示

java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub

		String fileName = request.getParameter("name");
		
		File file = new File("D:/upload", fileName);
		
		FileInputStream in = new FileInputStream(file);
		//如果文件名中包含中文,需要进行url编码
		fileName = URLEncoder.encode(fileName, "utf-8");
		//设置content-Disposition
		response.setHeader("Content-Disposition","attachment;filename=" + fileName);
	
		//获取响应对象的输出流
		ServletOutputStream outputStream = response.getOutputStream();
		
		//文件拷贝
		byte[] buff = new byte[1024];
		int len = -1;
		while((len = in.read(buff)) != -1){
			outputStream.write(buff, 0, len);
		}
		
		//关闭流
		in.close();
		outputStream.close();
	}

附录

配置上传的资源的访问路径

img

比如选中D:/upload的路径

img

img

注意:Application Context中路径可以根据需求设置