JavaWeb中文件的上传和下载

文件上传

文件上传指的是 通过 浏览器 向服务器 上传 某个文件,服务器 接收 到该文件 后 会 将 该文件 存储在 服务器的
硬盘中,通常 不会存在 数据库,这样可以 减轻数据库 的压力并且在文件的 操作上 更加灵活,常见的功能是上传头像图片。

文件上传的原理
所谓的 文件上传 就是服务器端通过 request对象 获取输入流,将浏览器 端上传的 数据读取 出来,保存到 服务器端。

文件上传的要求

  • 提供form表单,表单 的提交方式 必须是post
  • form表单中的 enctype 属性 必须是 mutipart/form-data
  • 表单中 提供 input type="file"上传 输入域

创建一个upload.jsp的文件,里面提供上传的按钮:

	<form action="${pageContext.request.contextPath }/upload5" method="post"  enctype="multipart/form-data">
				<input type="file" name="photo"><br>
				<input type="submit" value="上传"><br>
		
		</form>

创建Servlet用来处理用户上传的文件

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//获取 请求的 输入流
		InputStream is = request.getInputStream();
		
		//读取输入流中的数据
		int len = 0;
		byte[] b = new byte[1024];
		
		while((len=is.read(b))!=-1) {
			//打印文件的字节内容
			System.out.println(new String(b,0,len));
		}
	}

FileUpload工具的使用

在实际开发中通常 会 借助第三方 工具实现上传功能,应用较多的是apache旗下sh的 Commons-fileupload。Apache开源组织提供 一个用来 处理表单文件上传的开源组件(Commons-fileupload),该组件性能优异,并且其API使用极其简单,可以让开发人员轻松实现Web文件上传功能,因此自web开发中实现文件上传功能,通常使用 Commons-fileupload组件实现。在使用 该工具 实现上传功能时,首先 需要导入Commons-fileuploads和commons-io两个jar包。

代码实例

**
 * 使用common fileupload完成上传
 */
public class UploadServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//1、判断表单是否支持文件上传。 即:  enctype = "multipart/form-data"
		boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
		if(!isMultipartContent) {
			throw new RuntimeException("该请求不能完成文件上传");
		}
		
		//2、创建一个 DiskFileItemfactory对象
		DiskFileItemFactory factory = new DiskFileItemFactory();  //factory
		//3、创建一个ServletFileUpload对象,该对象是上传的核心组件
		ServletFileUpload sfu = new ServletFileUpload(factory);
		
		//4、解析request对象,并得到 一个表单项的 集合
		try {
			
			List<FileItem> fileItems = sfu.parseRequest(request);
			//5、遍历该集合,集合中的每一项 即为 每一个表单项
			for(FileItem item:fileItems) {
				if(item.isFormField()) {
					//普通表单项,不是文件项
					//等价于以前的  request.getParameter()
					String fieldname = item.getFieldName(); //字段名
					String fieldvalue = item.getString("UTF-8"); //字段值
					System.out.println(fieldname+"="+fieldvalue);
				}else {
					//上传表单项
					//获取文件名
					String fileName = item.getName();
					//获取输入流
					InputStream is = item.getInputStream();
					//创建输出流
					String path = this.getServletContext().getRealPath("/upload");
					//获得 文件在服务器上上传的 路径
					File file = new File(path,fileName);
					FileOutputStream fos = new FileOutputStream(file);
					
					//完成文件的复制
					byte[] bytes = new byte[1024];
					int len = -1; 
					//从客户端 读取数据 并将其 写到  服务器端的 硬盘上
					while((len=is.read(bytes))!=-1) {
						fos.write(bytes, 0, len);
					}
					
				}
			}
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

解析原理:
在这里插入图片描述

临时目录

文件由浏览器通过网络上传到服务器,并不是直接通过一条网络线路将所有请求数据发送到了服务器的。而是将这些数据分为了很多个数据包,这些数据包分别被编号后,经由不同的网络线路最终发送到了服务器中。这些数据包到达服务器的时间会根据不同的网络线路的情况不同,分别先后到达服务器,顺序是不定的。因此服务器会在其临时目录中,创建一个临时文件,将这些数据包进行拼接组装。Tomcat 默认情况下的临时目录是 Tomcat 服务器安装目录的 temp 子目录。我们也可以修改临时目录的默认位置。Apache 的 FileUpload 支持设置创建临时文件的最小临界值,即只有上传的文件大小超出这个值,才会创建临时文件。通过 DiskFileItemFactory 的 setSizeThreshold()方法可以设置临界值,单位为字节。通过 DiskFileItemFactory 的 setRepository()方法可以指定临时目录。

需要注意的是将temp文件夹中的临时文件删除,这个需要在IO流关闭之后才能删除。

当上传的文件大小 超过 10kb时 就会 将文件 放到 临时目录中 了。10kb是默认值,可以通过DiskFileItemFactory中的setSizeThreshold方法修改:
factory.setSizeThreshold(102410243);
上面代码的作用是当上传文件大小超过3MB时 才会是用那个临时文件。

在这里插入图片描述

上传文件的大小

对于上传文件的大小,可以通过 ServletFileUpload的setFileSizeMax()与setSizeMax()方法进行控制。setFileSizeMax()用于设置单个文件上传的最大值,而setSizeMax()用于设置 单次上传的最大值,

创建目录

无论是 Windows 系统、Linux 系统,还是其它系统,其目录中所包含的文件数量是有上
限的。所以对于上传的文件,应该分目录进行管理。若文件较多,则可按照年、月、日创建多级子目
录。这样,即方便管理,又不会超出目录的文件数量上限。

//获取输入流
InputStream is = item.getInputStream();
//创建输出流
String path = this.getServletContext().getRealPath("/upload");


//获取当前系统时间的年月日
LocalDate now = LocalDate.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();

//在upload下分别创建年、月、日三级子目录
path = path + "/" + year + "/" + month + "/" +day;
//创建父目录
File parentDir = new File(path);
//如果父目录不存在,则创建
if(!parentDir.exists()){
    parentDir.mkdirs();
}

文件下载

超链接下载
超链接下载是指,将下载 资源作为 超链接 的连接目的文件出现。若 浏览器 可以 解析 该资源文件,则将 在浏览器上 直接 显示文件内容;若浏览器不支持 文件的解析,则会 弹出 另 存为 对话框,要求 用户保存。
在WebContent文件夹下创建download文件夹,里面 放入一些文件:
创建jsp:

使用超链接下载文件<br>
		<a href="${pageContext.request.contextPath }/download/buhuo.JPG">下载图片</a>
		<a href="${pagecontext.request.contextPath }/download/MySQL常用命令.zip">下载压缩包</a>
		<br>

使用servlet实现下载
若要 使得 下载 的文件 以附件的形式 出现在 浏览器中,则需要设置 响应头的属性 content-disposition的值为 attachment,且 需要 指定浏览器 下载 后显示的文件名。 即需要指定 content-disposition的值为attachment;filename=文件名。

package com.monkey1024.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 文件下载
 */
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应头属性值,使文件以附件形式进行下载
        response.setHeader("content-disposition", "attachment;filename=monkey1024.png");

        //获取输入流
        InputStream is = this.getServletContext().getResourceAsStream("/download/monkey1024.png");
        ServletOutputStream os = response.getOutputStream();

        //复制文件
        byte[] bytes = new byte[1024];
        int len = 1;
        while((len = is.read(bytes)) != -1){
            os.write(bytes, 0, len);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

创建jsp:
在这里插入图片描述
解决文件名乱码问题:

//这里设置的是文件下载下来的名字
		String fileName = "123.JPG";
		fileName = new String(fileName.getBytes("utf-8"),"iso8859-1");
		
		//设置 响应头属性,使文件 以附件形式下载
		response.setHeader("content-disposition",  "attachment;filename="+fileName);
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值