使用场景
各大网站中都会用到文件上传功能,如个人简历的照片,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();
}