引言:文件的上传和下载是我们在web开发时候经常要用到的一个模块,今天就这个模块进行一下详细的说明。
- 文件上传
- 文件上传分为两个部分,一部分是servlet3.0以前的文件上传方式,主要借助commons-fileupload组件。代码如下:
@WebServlet("/upload")
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/views/upload.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
//设置上传路径
File file = new File("G:/upload");
//如果这个文件夹不存在,就创建
if(!file.exists()) {
file.mkdir();
}
//上传临时路径
File tempFile = new File("G:/uploadtemp");
if(!tempFile.exists()) {
tempFile.mkdir();
}
if(ServletFileUpload.isMultipartContent(req)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲区大小
factory.setSizeThreshold(1024 * 10);
//设置临时文件夹
factory.setRepository(tempFile);
ServletFileUpload fileupload = new ServletFileUpload(factory);
//设置最大文件大小
fileupload.setFileSizeMax(1024 * 1024 * 10);
try {
List<FileItem> itemList = fileupload.parseRequest(req);
for(FileItem item : itemList) {
//表单元素分为文件元素和普通元素
if(item.isFormField()) {
//普通元素
String fileName = item.getFieldName();
String value = item.getString("UTF-8");
System.out.println("fileName:" + fileName);
System.out.println("value: " + value);
}else{
//文件元素
String name = item.getName();
String fileName = item.getFieldName();
System.out.println("fileName:" + fileName);
System.out.println("name: " + name);
String newName = UUID.randomUUID().toString() + name.substring(name.lastIndexOf("."));
InputStream input = item.getInputStream();
FileOutputStream output = new FileOutputStream(new File(file,newName));
IOUtils.copy(input, output);
/*byte[] buffer = new byte[512];
int len = -1;
while((len = input.read(buffer))!= -1) {
output.write(buffer, 0, len);
}*/
System.out.println(name + "上传成功");
output.flush();
output.close();
input.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}else{
throw new ServletException("请设置form表单的entype属性");
}
}
}
相比servlet3.0以前的很麻烦,且很难读懂的代码而言(其实我自己也不是很明白,只是知道应该这么写而已),servlet3.0+有了全新的文件上传方式,这种代码看起来更加明了清晰。
注意点:- 添加MultipartConfig注解
@WebServlet("/upload2")
@MultipartConfig
public class UploadServlet2 extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/views/upload2.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
//servlet3.x上传文件可以通过req.getParameter()获取普通表单的值
String desc = req.getParameter("desc");
System.out.println("desc:" + desc);
//获取part对象
Part part = req.getPart("file");
//文件元素的值
String name = part.getName(); //name属性值
String contentType = part.getContentType(); //MIME类型
long size = part.getSize(); //文件大小
String filename = part.getSubmittedFileName();//上传文件名称
//将文件大小改成可读的
String readSize = FileUtils.byteCountToDisplaySize(size);
//上传路径
File file = new File("G:/upload");
if(!file.exists()) {
file.mkdir();
}
//这一部分是给新上传的文件一个永不重复的文件名
String newName = UUID.randomUUID().toString()
+ filename.substring(filename.lastIndexOf("."));
InputStream input = part.getInputStream();
OutputStream output = new FileOutputStream(new File(file,newName));
IOUtils.copy(input, output);
System.out.println(filename + "上传成功");
output.flush();
output.close();
input.close();
}
}
- 下面说一下文件下载,其实原理都是一样的,上传和下载都必须把文件转换为流的形式进行操作,上传的时候,是把文件流读进来,往电脑硬盘里写的时候应该新new 一个输出流,然后用Commons的IOUtil copy一下,下载的时候这个正好是相反的,应该是new 一个输入流,将服务器中的文件读入流中,再通过response对象获取输出流,之后用IoUtil进行copy。具体代码如下:
@WebServlet("/download")
public class DownloadServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String fileName = req.getParameter("file");
String downloadName = req.getParameter("downloadName");//"我的照片.jpg";
File saveDir = new File("G:/upload");
File file = new File(saveDir,fileName);
if(file.exists()){
if(StringUtils.isNotEmpty(downloadName)) {
downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");
//设置MIME类型
resp.setContentType("application/octet-stream");
//resp.addHeader("content-type", "application/octet-stream");
//设置文件名,添加响应头attachment; filename="hello.jpg"
resp.addHeader("Content-Disposition", "attachment; filename=\"" + downloadName + "\"");
}
InputStream input = new FileInputStream(file);
OutputStream output = resp.getOutputStream();//这是
IOUtils.copy(input, output);
output.flush();
output.close();
input.close();
} else{
resp.sendError(404,"路径错误");
}
}
}