servlet 表单文件上传

使用场景

各大网站中都会用到文件上传功能,如个人简历的照片,excel的上传等

注意事项

客户端可采用表单上传的方式,但需要注意表单
要设置enctype=“multipart/form-data”,method=“post” ,文件域要设置type=“file”
服务器端要接收文件需从request中获取流
第一种解决方式:

//获取流
InputStream inputStream = req.getInputStream();
//保存文件
File file = new File("D:/test.txt");
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bs = new byte[1024];
while (inputStream.read(bs) != -1) {
	outputStream.write(bs);
}
inputStream.close();
outputStream.close();
resp.getWriter().print("success");

不难发现这时虽然能够将传递文件中的内容保存还保存了额外的内容
在这里插入图片描述
现在的问题是如何解决只获取文件域的内容进行保存呢
可以使用借助javax.servlet.http.Part类来实现,签体是类要使用@MutipartConfig注解

//获取流
Part part = req.getPart("file");
InputStream inputStream = part.getInputStream();
//保存文件
File file = new File("D:/test.txt");
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bs = new byte[1024];
while (inputStream.read(bs) != -1) {
	outputStream.write(bs);
}
inputStream.close();
outputStream.close();
resp.getWriter().print("success");

此时获取的将只有文件的内容。
真实环境下D盘不一定存在,现在我们想让文件保存在服务器的upload路径下如何实现呢

//获取流
Part part = req.getPart("file");
InputStream inputStream = part.getInputStream();
//保存文件
String path=getServletContext().getRealPath("upload/");
File fileDir=new File(path);
if(!fileDir.exists()) {
	fileDir.mkdir();
}
File file = new File(path+"test.txt");
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bs = new byte[1024];
while (inputStream.read(bs) != -1) {
	outputStream.write(bs);
}
inputStream.close();
outputStream.close();
resp.getWriter().print("success");

这时不难发现文件名和文件类型不是我们想要的,我们想要上传时的文件名,且中文不乱码如何如理呢?

//防止中文乱码
req.setCharacterEncoding("utf-8");
//获取流
Part part = req.getPart("file");
InputStream inputStream = part.getInputStream();
//保存文件
String path=getServletContext().getRealPath("upload/");
File fileDir=new File(path);
if(!fileDir.exists()) {
	fileDir.mkdir();
}
File file = new File(path+part.getSubmittedFileName());
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bs = new byte[1024];
while (inputStream.read(bs) != -1) {
	outputStream.write(bs);
}
inputStream.close();
outputStream.close();
resp.getWriter().print("success");

这时发现我们上传的文件文件名可能重复,如何来解决这个问题呢?

//获取流
Part part = req.getPart("file");
InputStream inputStream = part.getInputStream();
//保存文件
String path=getServletContext().getRealPath("upload/");
File fileDir=new File(path);
if(!fileDir.exists()) {
	fileDir.mkdir();
}
String sufix = fileName.substring(fileName.lastIndexOf(".",fileName.length()));
String newName=UUID.randomUUID()+"";
File file = new File(path+newName+sufix);
File file = new File(path+part.getSubmittedFileName());
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bs = new byte[1024];
while (inputStream.read(bs) != -1) {
	outputStream.write(bs);
}
inputStream.close();
outputStream.close();
resp.getWriter().print("success");

如果上传的是多个文件呢?
首先 文件域中要加 multiple属性
其次服务器端接收多个文件

req.setCharacterEncoding("utf-8");
String name=req.getParameter("name");
for(Part part:req.getParts()) {
	if(part.getContentType()!=null) {				
		InputStream inputStream = part.getInputStream();
		String path = getServletContext().getRealPath("upload/");
File fileDir = new File(path);
if (!fileDir.exists()) {
	fileDir.mkdir();
}
String fileName = part.getSubmittedFileName();
System.out.println(fileName);
/* File file=new File(path+fileName); */
String sufix = fileName.substring(fileName.lastIndexOf(".", fileName.length()));
String newName = UUID.randomUUID() + "";
	File file = new File(path + newName + sufix);
	FileOutputStream outputStream = new FileOutputStream(file);
	byte[] bs = new byte[1024];
	while (inputStream.read(bs) != -1) {
		outputStream.write(bs);
	}
	inputStream.close();
	outputStream.close();
}else {
	//文本域内容
		String textValue=req.getParameter(part.getName());
	}
}

resp.getWriter().print("success");

文件部分可直接使用part.write(path);
在servlet3.0前常借助其他组件来完成文件上传,最常用的是apache commons-fileupload 组件,这个组件需要和commons-io组件组合使用

req.setCharacterEncoding("utf-8");
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sUpload = new ServletFileUpload(factory);
try {
	List<FileItem> files = sUpload.parseRequest(req);
	for (FileItem fileItem : files) {
		if (fileItem.isFormField()) {
			System.out.println(fileItem.getFieldName() + "value:" + fileItem.getString());
		} else {
			String path = getServletContext().getRealPath("upload/" + fileItem.getName());
			fileItem.write(new File(path));
		}
	}
} catch (FileUploadException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值