Java原生实现文件上传

【1】几个核心类和接口

① DiskFileItemFactory类

将请求消息实体中的每一个项目封装成单独的 (FileItem接口的实现) 对象的任务。由 org.apache.commons.fileupload.FileItemFactory 接口的默认实现 org.apache.commons.fileupload.disk.DiskFileItemFactory 来完成。

当上传的文件项目比较小时,直接保存在内存中(速度比较快),比较大时,以临时文件的形式,保存在磁盘临时文件夹(虽然速度慢些,但是内存资源是有限的)。

通常通过该工厂设置一些限制,如单个文件上传最大值。文件上传组件核心处理类就是使用该工厂创建的:

ServletFileUpload upload = new ServletFileUpload(factory);

② ServletFileUpload 类

org.apache.commons.fileupload.servlet.ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。

使用其 parseRequest(HttpServletRequest) 方法可以将表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回,使用该方法处理上传文件简单易用。

List<FileItem> items = upload.parseRequest(request);

那么FileItem是什么呢?

③ FileItem

FileItem类用来封装单个表单字段元素的数据。一个表单字段元素对应一个FileItem对象,通过调用FileItem对象的方法可以获得相关表单字段元素的数据。FileItem是一个接口,在应用程序中使用的实际上是该接口一个实现类,该实现类的名称并不重要,程序可以采用FileItem接口类型来对它进行引用和访问,为了便于讲解,这里将FileItem实现类称之为FileItem类。FileItem类还实现了Serializable接口,以支持序列化操作。

如下方式可以获取FileItem中的key-value:

filedName = fi.getFieldName();
InputStream in = fi.getInputStream();
StringBuffer sb = new StringBuffer();
byte[] b = new byte[4096];

int n;
while((n = in.read(b)) != -1) {
     sb.append(new String(b, 0, n, "UTF-8"));
}

this.log.debug("field_name=" + filedName + " value=" + sb.toString());
params.put(filedName , sb.toString());

【2】代码实现

① 后台Servlet

package com.file.servlet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
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;


public class UploadServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text;charset=UTF-8");
		/*使用输入流读取*/
//		String file = request.getParameter("file");
//		String desc = request.getParameter("desc");
//		System.out.println(file+","+desc);
//		InputStream in2 = request.getInputStream();
//		Reader reader = new InputStreamReader(in2);
//		BufferedReader bufferedReader = new BufferedReader(reader);
		/*逐行读出*/
//		String str = null;
//		if ((str = bufferedReader.readLine())!=null) {
//			System.out.println(str);
//			
//		}
		/*1.得到FiletItem的集合Items*/
		DiskFileItemFactory factory = new DiskFileItemFactory();
		/*设置单位文件最大500K,只要超过500k,将会先上传到临时目录下面*/
		factory.setSizeThreshold(1024*500);
		
		/*创建临时目录*/
		File temDirectory = new File("d:\\temDirectory");
		if (!temDirectory.exists()) {
			temDirectory.mkdir();
		}
		//设置临时目录
		factory.setRepository(temDirectory);
		/*create a new file upload handler*/
		ServletFileUpload upload = new ServletFileUpload(factory);
		/*the all max to be 10M*/
		upload.setSizeMax(1024*1024*10);
		
		/*2.遍历items,若是一个一般的表单域,打印信息;若是文件域保存到硬盘一个位置*/
		try {
			List<FileItem> items = upload.parseRequest(request);
			
			for(FileItem item:items){
				if (item.isFormField()) {
					/*获取文件原始名*/
					//String name = item.getName();
					/*获取表单域中的文件名*/
					String filedName1 = item.getFieldName();
					String value = item.getString();
					
					System.out.println(filedName1+"--"+value);
				}else {
					//获取表单中标签的name属性值
					String filedName = item.getFieldName();
					//获取表单中上传的文件名
					String fileName = item.getName();
					/*若返回的为路径+文件名,则需要截取*/
					int index=fileName.lastIndexOf("\\");
					//System.out.println(index);
					if(index!=-1) {
						/*从索引出开始知道字符串末尾 索引从“0”开始*/
						fileName=fileName.substring(index+1);
					}
					String contentType = item.getContentType();
					long sizeInBytes = item.getSize();
					
					System.out.println("filedName :"+filedName);
					System.out.println("fileName :"+fileName);
					System.out.println("contentType :"+contentType);
					System.out.println("sizeInBytes :"+sizeInBytes);
					//判断文件拓展名是否符合规则
					String extendName = fileName.substring(fileName.indexOf("."), fileName.length());
	                    String reg="^jpg||jpeg||png||doc||docx||pdf$";
	                    boolean matches = Pattern.matches(reg, extendName.substring(1));
	                    System.out.println("文件名是否匹配 :"+matches);
	                    if (!matches) {
	                    	 response.setContentType("text/html; charset=utf-8"); 
	                         PrintWriter outWriter = response.getWriter();
	                         JSONObject jsonObject = new JSONObject();
	                         jsonObject.put("code", "false");
	                         jsonObject.put("path", "");
	                         jsonObject.put("msg", "文件格式不对");
	                         outWriter.print(jsonObject.toJSONString());
	                         outWriter.close();
	                         return ;
					}
					/*从item拿到输入流*/
					InputStream in = item.getInputStream();
					byte[] buffer = new byte[1024];
					int len = 0;
					/*也可称为filePath,文件保存到磁盘的路径+名字*/
					//上传到本机D盘
					//fileName = "d:\\files\\"+fileName;
					//上传服务器目录下D:\apache-tomcat-7.0.40\webapps\JAVAWeb-FileUpload\resources\1.jpg
					String path = getServletContext().getRealPath("/");
					fileName = path+"resources\\"+fileName;

					//上传到本机D盘 D:\\upload\resources
					//fileName = "D:\\upload\\resources\\"+fileName;
					//此时jsp若想请求该图片,则需要在Tomcat做目录映射,请查阅目录映射资料
					System.out.println(fileName);
					/*获取输出流并读出到files目录下*/
					File fileCreate = new File(fileName);
					File pFileCreate = fileCreate.getParentFile();
//					System.out.println("fileCreate.getParent(),"+fileCreate.getParent());
//					System.out.println("fileCreate.getPath(),"+fileCreate.getPath());
//					System.out.println("fileCreate.getParentFile(),"+pFileCreate);
					/*
					 *  fileCreate.getParent(),d:\files
						fileCreate.getPath(),d:\files\1.jpg
						fileCreate.getParentFile(),d:\files
					  */
					//judge the parent path exist,if not ,create it !
					if (!pFileCreate.exists()) {
						pFileCreate.mkdirs();
					}
//					if (!fileCreate.exists()) {
//						fileCreate.createNewFile();
//					}
					OutputStream out = new FileOutputStream(fileCreate);
					/*从输入流读到buffer里面,一次1024个字节*/
					while((len = in.read(buffer))!=-1){
						
						out.write(buffer,0,len);
					}
					/*关闭输入输出流*/
					out.close();
					in.close();
					//设置编码,避免上传成功出现乱码
					response.setContentType("text/html; charset=utf-8"); 
					PrintWriter outWriter = response.getWriter();
//					outWriter.print("<script>alert('上传成功');</script>");
					//上传成功后返回到index页面
					outWriter.print("<script>alert('上传成功');window.location.href='index.jsp';</script>");
					outWriter.close();
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}

}


② JSP页面

<form action="uploadServlet" method="post" enctype="multipart/form-data">
		File:<input type="file" name="file"/>
		Desc:<input type="text" name="desc"/><br><br>
		<input type="submit" value="Submit"/>
	
	</form>

③ result

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值