文件上传的简单实现

两个依赖包

commons-fileupload-1.3.2、commons-io-2.5.jar。
可以从官网下载最新版本commons-fileuploadcommons-io

注意事项

  1. 表单 enctype 属性应该设置为 multipart/form-data
    enctype 决定了表单打包数据文件的方式,有如下几种取值:
        a. application/x-www-form-urlencoded。默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
        b. multipart/form-data 。 指定传输数据为二进制类型,比如图片、mp3、文件。
        c. text/plain。纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。
    默认方式不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据。

  2. 表单method属性必须是post
        a. method=’get’ 编码后的表单内容附加在请求连接后
        b. method=’post’ 编码后的表单内容作为post请求的正文内容
    get方法会导致将文件加到url后面,这里必须要用posts

核心API

1. DiskFileItemFactory
    a. setSizeThreshold(int sizeThreshold) :设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时,fileupload组件将使用临时文件缓存上传文件。
    b. setRepository(Java.io.File repository) :指定临时文件目录,默认值为System.getProperty(“java.io.tmpdir”).

2. ServletFileUpload:
    a. isMultipartContent(request):检测是否为多媒体上传 判断enctype属性是否为multipart/form-data
    b. setFileSizeMax(long fileSizeMax) :设置上传文件的最大值(单个文件),用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。

    c. setSizeMax(long sizeMax) :设置上传文件总量的最大值(所有上传文件),用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。

    d. setHeaderEncoding(java.lang.String encoding) :设置编码格式。在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回

    e. List parseRequest(HttpServletRequest request):解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合

3. FileItem
    a. isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。

实现步骤

  1. 创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录。
  2. 使用DiskFileItemFactory 对象创建ServletFileUpload对象,并设置上传文件的大小限制。
  3. 调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容的List对象。
  4. 对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件:若是则上传

代码实现

结构图:结构图

upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传练习</title>
</head>
<body>
<form action="UploadServlet" method="post" enctype="multipart/form-data">
	选择一个文件<br>
	<input type="file" name="filename"><br>
	<br>
	<br>
	<input type="submit" value="提交">

</form>

</body>
</html>

UpLoadServlet.java

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class UploadServlet
 */
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	
	private static final String Upload_Directory = "upload";
	private static int Max_sizeThreshold=1024 * 1024 * 3;
	private static int Max_filesize=1024 * 1024 * 3;
	private static int Max_size=1024 * 1024 * 3;
	
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//检测是否为多媒体上传  判断enctype属性是否为multipart/form-data
		if(!ServletFileUpload.isMultipartContent(request)){
			//不符合条件 停止上传
			System.out.println("Error:上传失败,表单必须包含 enctype=multipart/form-data");
			PrintWriter writer=response.getWriter();
			writer.println("Error:上传失败,表单必须包含 enctype=multipart/form-data");
			writer.flush();
			return;
		}
		//配置上传参数
		DiskFileItemFactory factory=new DiskFileItemFactory();
		//设置缓冲区大小
		factory.setSizeThreshold(Max_sizeThreshold);
		//设置临时存储目录
		factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
		
		ServletFileUpload upload=new ServletFileUpload(factory);
		//最大文件上传值(文件大小限制)
		upload.setFileSizeMax(Max_filesize);
		//最大上传数(请求数)
		upload.setSizeMax(Max_size);
		upload.setHeaderEncoding("UTF-8");
		
		//构造临时路径路径,即相对于当前应用的目录
		String uploadpath=request.getServletContext().getRealPath("/")+Upload_Directory;
		
		File uploadDir=new File(uploadpath);
		if(!uploadDir.exists()){
			uploadDir.mkdir();//不存在该路径 则创建
		}
		
		try {
			//解析请求内容 提取文件数据
			List<FileItem> formItems=upload.parseRequest(request);
			
			if(formItems !=null && formItems.size()>0){
				for(FileItem item:formItems){
					//判断是普通文本表单字段,还是一个文件表单字段
					if(!item.isFormField()){
						//是文件时
						String filename=new File(item.getName()).getName();
						String filepath=uploadpath + File.separator + filename;
						File storeFile = new File(filepath);
						System.out.println(filepath);
						item.write(storeFile);
						request.setAttribute("message", "文件上传成功");
					}
				}
			}
		} catch (Exception e) {
			request.setAttribute("message", "错误信息"+e.getMessage());
		}
		request.getServletContext().getRequestDispatcher("/message.jsp").forward(request, response);
		
	}

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

}

如果不是直接添加的servlet文件,那么还需要自己在配置文件web.xml内添加如下代码

  <servlet>
    <description></description>
    <display-name>UploadServlet</display-name>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>UploadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/UploadServlet</url-pattern>
  </servlet-mapping>

message.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传结果</title>
</head>
<body>
	<center>
		<h2>${message}</h2>
	</center>
</body>
</html>

个人疑惑点知识拓展

  1. System.getProperty(“java.io.tmpdir”):输出的是系统的临时目录
        一般情况下(不再服务器内发布,即普通的java工程的main里面),对应的临时路径为:win:C\Users\用户名\AppData\Local\Temp
        当程序在Tomcat下时,该路径变为tomcat安装目录下的temp文件,我的对应为:D:\Eclipse01\apache-tomcat-7.0.52\temp

  2. 跨平台使用绝对路径利用File.separator
    File.separator 的作用相当于 ’ \ ',windows系统下能识别但是 Linux 中不识别 ’ \ ’ ,而 File.separator 是系统默认的文件分隔符号,在任何系统中使用都不会出错

  3. 将文件上传到项目目录里面而非服务器目录的方法:在\tomcat-7.0.23\conf\server.xml 文件里配置文件设置虚拟目录
    具体实现参考:Tomcat学习笔记(三)——虚拟目录及虚拟子目录篇

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值