fileupload实现文件上传

本文深入解析使用Apache Commons FileUpload组件实现文件上传的过程,包括解析请求、处理普通字段和文件上传的具体步骤,以及如何确保文件安全存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package cn.zlz.upload.servlelt;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;

public class UploadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			//创建解析工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			factory.setRepository(new File("d:\\temp"));//设置临时文件存储路径,一般都是默认,不用自己设置
			//创建fileupload组件
			ServletFileUpload fileUpload = new ServletFileUpload(factory);
			//解析request
			List<FileItem> fileitems = fileUpload.parseRequest(request);
			//遍历集合
			for(FileItem item:fileitems){
				//判断是否是普通字段
				if(item.isFormField()){
					String name=item.getFieldName();	//获得的是输入框的名字
					String value=item.getString("utf-8");		//输入框里面提交的值,过滤器解决不了的,用这种方法
				}
				else{
					String name=item.getFieldName();	//获得的是输入框的名字
					String filename=item.getName();		//带有后缀名即类型的文件名
					//防止文件名重复,而且UUID里面没有_,这样后面直接根基_截取,再得到名字filename,给你显示
					//而且还要保证扩展名不变
					filename=UUID.randomUUID().toString()+"_"+filename;
				/*	filename=filename.substring(filename.lastIndexOf("\\")+1);
					System.out.println(filename+"截取的");若不是文件名我们截出文件名及扩展名*/
					
					//在服务器上创建同名的文件
					//随即获得16个目录,根基名字的,两层的就再搞一次,记住两层 要不一样啊,必须分文件夹啊,不然文件太多卡死
					int num1=filename.hashCode()&0xf;//通过hashcode就把名字变成32位的了,再与上一个16进制的15,就是只
					//取的后四位,这样根基名字获得目录,方便以后再去目录下找文件
					int num2=(filename.hashCode()>>4)&0xf;//右移四位获得一个目录
					String webpath="/upload/"+num1+"/"+num2+"/"+filename;		//这是web路径也是虚拟路径
					String path=getServletContext().getRealPath(webpath);	//根基虚拟路径得到绝对路径
					File file=new File(path);//根基绝对路径创建文件,建文件前一定要有文件夹啊
					file.getParentFile().mkdirs();	//根基父类建目录???、
					file.createNewFile();//当且仅当这个目录下没有该文件,创建一个空的文件
					
					//获得流
					InputStream in=item.getInputStream();//流从哪里来,就是从item读来的
					OutputStream out=new FileOutputStream(file);//要往文件中写,所以用File的
					
					//流的对拷
					/*int len;
					byte[] buffer=new byte[1024];
					while((len=in.read(buffer))>0)
						out.write(buffer, 0, len);
					in.close();
					out.close();
					}*/
					Streams.copy(in,out,true);//fileupload提供的封装复制文件的东西,true表示关流
				   item.delete();//复制完了就删除临时文件。
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值