文件上传和下载
本文章基于B站UP主:楠哥教你学Java 的课程《Java Web从入门到实战【完整版】》进行整理补充,本文章仅用于个人学习交流使用。
1.文件上传
1、 input 的 type 设置为 file
2、 form 表单的 method 设置 post ( get 请求会将⽂件名传给服务端,⽽不是⽂件本身)
3、 form 表单的 enctype 设置 multipart/form-data,以⼆进制的形式传输数据
<当传输数据时,会将浏览器的信息获得并输出>
1.一般方式
读取本地文件并输出在控制台和保存在项目中
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form enctype="multipart/form-data" action="upload" method="post">
<input type="file" name="img"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
UploadServlet.java
package com.lut.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过输入流获取客户端传来的数据流
InputStream inputStream= req.getInputStream();//IO流获取数据,字节流
Reader reader=new InputStreamReader(inputStream,"utf-8");//转化成字节流,设置编码格式,处理中文乱码
BufferedReader bufferedReader=new BufferedReader(reader);//缓冲流
//通过输出流将数据输出到本地硬盘
//获取文件夹的绝对路径
//在 out 里面新建file文件夹
String path=req.getServletContext().getRealPath("file/copy.txt");//将内容输出到file/copy.txt
OutputStream outputStream=new FileOutputStream(path);
Writer writer=new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter=new BufferedWriter(writer);
String str="";
while ((str=bufferedReader.readLine())!=null){
System.out.println(str);
bufferedWriter.write(str);
}
//关闭流
bufferedWriter.close();
writer.close();
outputStream.close();
bufferedReader.close();
reader.close();
inputStream.close();
}
}
存在问题:保存在项目中的文件会出现多余的浏览器信息,并且缺少换行符
2.使用 fileupload 组件
在WEB-INF文件下创建lib文件夹,在Libraries 中进行引入
需要引入:commons-fileupload-1.4.jar 和 commons-io-2.5.jar
fileupload 组件可以将所有的请求信息都解析成 FileIteam 对象,可以通过对 FileItem 对象的操作完成上传,⾯向对象的思想。
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form enctype="multipart/form-data" action="upload" method="post">
<input name="desc" type="text"><br>
<input name="file" type="file"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
注:使用字符流读取会无法读取换行符,读取图片时或破坏其内部结构,导致图片无法正常显示,但使用字节流读取便不会出现这样的问题
UploadServlet.java
package com.lut.servlet;
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;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try{
DiskFileItemFactory fileItemFactory=new DiskFileItemFactory();
ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
List<FileItem> list=servletFileUpload.parseRequest(req);
System.out.println(list);
//[name=1.txt, StoreLocation=null, size=172 bytes, isFormField=false, FieldName=img]
for (FileItem fileItem:list){
//fileItem.isFormField()=true,是一个文本框
if(fileItem.isFormField()){
String name=fileItem.getFieldName();// input的name :img
String value=fileItem.getString("utf-8");
System.out.println(name+" "+value);
}else {
String fileName=fileItem.getName();//文件名 1.txt
long size=fileItem.getSize();
System.out.println(fileName+" "+size+"Byte");
InputStream inputStream=fileItem.getInputStream();
String path=req.getServletContext().getRealPath("file/"+fileName);
OutputStream outputStream=new FileOutputStream(path);
int temp=0;
while ((temp=inputStream.read())!=-1){
outputStream.write(temp);
}
outputStream.close();
inputStream.close();
System.out.println("上传成功");
}
}
}catch (FileUploadException e){
e.printStackTrace();
}
}
}
功能展示:
上传文本和照片:
上传成功后会将内容保存在 out 文件夹下面:
2.文件下载
download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/download?type=png">1.png</a>
<a href="/download?type=txt">1.txt</a>
</body>
</html>
DownloadServlet.java
package com.lut.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String type=req.getParameter("type");
//根据文件类型设置文件下载名
String fileName="";
switch (type){
case "png":
fileName="1.png";
break;
case "txt":
fileName="1.txt";
}
//设置响应方式
resp.setContentType("application/x-msdownload");
//启动下载器
resp.setHeader("Content-Disposition","sttachment;filename="+fileName);
OutputStream outputStream=resp.getOutputStream();//获取输出流
String path=req.getServletContext().getRealPath("file/"+fileName);
InputStream inputStream=new FileInputStream(path);
int temp=0;
while ((temp=inputStream.read())!=-1){
outputStream.write(temp);
}
inputStream.close();
outputStream.close();
}
}
功能展示:
主界面:
下载成功:
**注意:**文件可以下载之前,file 文件夹里面的内容必须同步到 out 文件夹下面,否则下载时会出现错误, 如果没有同步过去,可以手动重新打包(IDEA工具栏:Bulid–>Rebulid Progect)
项目文件夹:
同步完成: