J2EE 文件上传下载

  • Tomcat 9

文件上传

  • 文件上传本质上是 I/O 读写

    • 客户端(浏览器)发送文件使用 HTTP 协议,将文件的内容写出去:客户端本地输入流 > 内容 > 网络输出流
    • 服务器(Web容器)接收文件使用 HTTP 协议,将文件的内容读过来:网络输入流 > 内容 > 服务器本地输出流
  • 一般使用外部包进行文件上传,常用的是 apache 组织提供的两个包

文件上传的步骤

知识补充:get 与 post 虽然对字节数都没有限制

  • 但 get 通过 URL 拼串,而不同浏览器对于 UR L处理长度有所不同
  • 但 post 需要 Web 容器的支持,与容器的处理性能有关,比如 Tomcat 默认无限制,但是可以通过修改 server.xml 配置文件中的 <Connector port="8080" maxPostSize="-1">

浏览器端

  1. JSP/HTML 文件中,表单通过 post 提交(不能使用 get,是由于 ServletFileUpload 类的规定)
  2. 表单中添加一个属性 enctype="multipart/form-date"
  3. 表单中使用 <input type="file"> 组件让用户选择上传的文件,不仅仅能得到文件名还可以将文件的内容读出来

服务器端

  1. 引入文件上传需要的jar包

  2. 控制层

//1.创建一个工厂
DiskFileItemFactory factory = new DiskFileItemFactory();

//2.创建一个 ServletFileUpload 对象,包含一个 factory
ServletFileUpload upload = new ServletFileUpload(factory);

//3.使用 upload 对象解析 request,得到一个 List<FileItem>
List<FileItem> itemList = upload.parseRequest(request);
  1. 业务逻辑
  • 对普通组件与文件的处理方式
for (FileItem item: itemList) {
	if (item.isFormField()) { //是普通组件
		
		String key = item.getFieldName(); //获取组件的 name 属性		
		String value1 = item.getString(); //获取组件的 value 属性
		String value2 = item.getString("UTF-8"); //该重载方法可以处理字符集
		
	} else { //是文件
		
		String fileName = item.getName(); //获取上传文件的真实文件名
		InputStream inputStream = item.getInputStream(); //读取网络输入流
		item.write(new File("文件路径")); //写,即保存上传的文件
		
	}
}
  • 注意:如果上传的文件较大,为了防止丢包会产生临时文件(Tomcat 容器默认存在 temp 文件夹下)
factory.setSizeThreshold(10240); //设置缓冲区大小,默认10240byte - 10KB
factory.setRepository(new File("路径")); //设置缓冲区位置
  • 还可以设置上传文件的大小限制(为了缓解服务器存储压力)
upload.setFileSizeMax(); //单个上传文件的大小限制
upload.setSizeMax(); //上传文件总大小限制
  • 监控文件上传进度
upload.setProgressListener(new ProgressListener(){

	//文件上传字节数达到4096个字节,就触发一次监听器
	
	public void update(long l, long l1, int i) {
		//第一个参数表示 已经上传的字节个数  
		//第二个参数表示 上传文件的总字节数
		//第三个参数表示 正在上传第几个组件
		...
	}
});

文件上传注意事项

  1. 浏览器端需要满足四个条件:form表单、post请求、enctype属性、file组件(一个或多个)
  2. 服务器端需要满足:factory工厂对象、upload对象、解析request方法得到 List<FileItem>
  3. 上传文件保存的路径
    • 放在一个固定的位置,可移植性不好
    • 放在当前工程的根目录下 String path = this.getServletContext().getRealPath("/");
  4. 最好限制一下文件上传的大小:单个、总体、缓冲区
  5. 如果文件上传出现文件名冲突的问题
    • 方法一:原来名字+用户+时间.原来后缀
      beauty_zgh_date.jpg
    • 方法二:用一个随机产生的名字当做保存在服务器中的文件名
      beauty.jpg > xxxxx.jpg
      然后将 beatuy、xxxxx、路径、用户、上传时间 它们的关联存起来
    • 方法三:一个随机名字创建一个文件夹
      beauty.jpg 放在文件夹里
      然后将 路径、用户、文件夹名、上传时间 它们的关联存起来
  6. 有些时候可能上传的文件需要控制文件类型
    自己设计方法

文件下载

文件下载就很简单了

浏览器端

发送请求,一般通过 a 标签

服务器端

  1. 接收需要下载的文件名
  2. 找到文件并创建输入流读取内容
  3. 处理一下响应时的中文字符
  4. 设置响应内容类型和状态
  5. response 创建输出流将内容响应回浏览器

如果服务端存储的文件名字含有中文,需要处理一下

fileName = URLEncoder.encode(fileName,"UTF-8");

文件下载实质上就是服务器向浏览器返回文件信息,如果想看到浏览器跳出弹出框

response.setContentType("application/x-msdownload");
response.setHeader("Content-disposition", "attachment;filename=" + fileName); //fileName变量存储文件名
J2EE中,文件上传的常用方式是使用Servlet API提供的MultipartConfig注解和Part接口。具体实现步骤如下: 1. 在Servlet类上添加MultipartConfig注解,指定文件上传的配置信息,如上传文件的大小限制等。 2. 在Servlet的doPost方法中,通过HttpServletRequest的getParts方法获取上传的文件。 3. 遍历获取到的Part集合,通过Part的getInputStream方法获取上传文件的InputStream流,然后将其保存到服务器端。 以下是一个简单的文件上传Servlet代码示例: ```java @WebServlet("/upload") @MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB maxFileSize = 1024 * 1024 * 10, // 10MB maxRequestSize = 1024 * 1024 * 50) // 50MB public class FileUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { for (Part part : request.getParts()) { String fileName = extractFileName(part); if (fileName != null && !fileName.isEmpty()) { part.write(getUploadPath() + File.separator + fileName); } } response.sendRedirect(request.getContextPath() + "/success.jsp"); } private String extractFileName(Part part) { String contentDisp = part.getHeader("content-disposition"); String[] tokens = contentDisp.split(";"); for (String token : tokens) { if (token.trim().startsWith("filename")) { return token.substring(token.indexOf("=") + 2, token.length()-1); } } return null; } private String getUploadPath() { return getServletContext().getRealPath("") + File.separator + "uploads"; } } ``` 这个Servlet可以接受多个文件上传,最大限制为50MB。在doPost方法中,遍历获取到的Part集合,将每个上传文件保存到服务器端的固定目录下。其中,extractFileName方法用于从请求头中获取上传文件的文件名,getUploadPath方法用于获取服务端保存文件的目录路径。最后,重定向到上传成功的页面。 需要注意的是,在使用MultipartConfig注解时,需要在web.xml文件中添加以下配置: ```xml <web-app> <multipart-config> <max-file-size>52428800</max-file-size> <!-- 50MB --> <max-request-size>104857600</max-request-size> <!-- 100MB --> <file-size-threshold>0</file-size-threshold> </multipart-config> </web-app> ``` 这个配置文件用于指定上传文件的大小限制。其中,max-file-size表示单个文件的最大大小,max-request-size表示所有上传文件的最大总大小,file-size-threshold表示上传文件的缓存大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值