一、文件上传
想要进行文件的上传下载,需要先在表单中设置 enctype = "multipart/form-data"
<%-- 此处需要声明enctype属性说明文件为多段传输--%>
<form action="/0729_JSPTest/inputPhoto" method="post" enctype="multipart/form-data">
请输入用户名:<input type="text" name="username">
<br>
<input type="file" name="photo" value="请上传头像">
<br>
<input type="submit" value="上传~">
</form>
然后为IDEA添加jar包依赖
在WEB-INF下新建lib文件夹,将commons-fileupload.jar 、 commons-io.jar加入依赖
编写ServletUpload类继承HttpServlet 并重写doPost方法
首先要判断请求头是否是多段数据,如果不是多段数据传输则无法实现文件上传
开始文件上传:
首先创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
因为接收到的文件未解析,所以需要创建一个解析器
创建一个解析上传文件的工具类ServletFileUpload,有参构造参数为工厂对象
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
因为接收到的文件如果是中文则会出现乱码,所以需要设置收到的上传文件的请求头的编码格式
servletFileUpload.setHeaderEncoding("utf-8");
因为要为浏览器回传提示,所以设置浏览器编码格式(在响应头中)
resp.setContentType("text/html;charset = utf-8");
因为表单提交的内容有多项,其中有普通表单项也有文件项,所以将收到的表单项存入List集合
解析器的.parseRequest方法解析上传的数据
List<FileItem> list = servletFileUpload.parseRequest(req);
遍历每个表单项目
for(FileItem fileItem : list)
{
使用.isFormField判断是否是普通表单类型
如果是普通的表单项
打印表单name和value到服务器控制台
在浏览器打印提示
否则
{
是文件,则使用write方法下载到服务器中
fileItem.write(new File("下载的路径" + fileItem.getName()));
}
}
完整代码:
package com.teen.JSPTest0729;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
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.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
/**
* @author teen
* @create 2021/7/29 18:36
*/
public class FileInputServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判断上传的数据是否是多段数据
if (ServletFileUpload.isMultipartContent(req))
{
//创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
//创建一个用于解析上传文件的工具类ServletFileUpload
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
// 这里就是中文文件名处理的代码,setHeaderEncoding设置请求头编码格式
servletFileUpload.setHeaderEncoding("utf-8");
//设置浏览器格式为utf-8
resp.setContentType("text/html;charset=utf-8");
try {
// 解析上传的数据,得到每个表单项
List<FileItem> list = servletFileUpload.parseRequest(req);
//判断每个表单项是文件还是普通类型
for (FileItem fileItem:
list) {
//如果是普通的表单项
if (fileItem.isFormField())
{
//输出到页面
//设置文本输出流
//写到浏览器会出现乱码
PrintWriter out = resp.getWriter();
//普通的表单使用getString来获取值
out.write("表单的name值:" + fileItem.getFieldName() + "<br>");
out.write("普通的表单:"+ fileItem.getString("UTF-8") + "<br>");
System.out.println("表单的name值:" + fileItem.getFieldName());
System.out.println("普通的表单:"+ fileItem.getString("UTF-8"));
}
else
{
//如果是文件,则下载到服务器
PrintWriter out = resp.getWriter();
out.write("表单的name属性:"+ fileItem.getFieldName() + "<br>");
out.write("上传的文件名:" + fileItem.getName() + "<br>");
System.out.println("表单的name属性:"+ fileItem.getFieldName());
System.out.println("上传的文件名:" + fileItem.getName());
fileItem.write(new File("F:\\JavaProject\\0729_JSPTest" + fileItem.getName()));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("已收到上传的文件");
}
}
在web.xml中配置servlet路径
<servlet>
<servlet-name>FileInputServlet</servlet-name>
<servlet-class>com.teen.JSPTest0729.FileInputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileInputServlet</servlet-name>
<url-pattern>/inputPhoto</url-pattern>
</servlet-mapping>
二、文件下载
同样需要在表单中添加属性
<form action="/0729_JSPTest/outputPhoto" method="post" enctype="multipart/form-data">
<input type="submit" value="下载~">
</form>
创建ServletDownload类继承HttpServlet
同样重写doPost方法
首先要获取文件名存入字符串
通过getServletContext()获取上下文对象(看样子应该是个HTTP Servlet静态方法)
ServletContext servletContext = getServletContext();
通过上下文对象获得文件类型
String mimeType = servletContext.getMimeType("文件名.jpg");
通过响应头来告诉浏览器将要下载的文件类型
resq.setContentType(mimeType);
告诉浏览器此文件为附件,并对文件名进行UTF-8进行加密,因为谷歌浏览器会主动使用UTF-8解密
String fileHeader = "attachment;fileName =" + URLEncoder.encode("文件名.jpg","UTF-8");
resp.setHeader("Content-Disposition",fileHeader);
通过getResourceAsStream("文件路径") 获取上下文的输入流
InputStream resourceStream = servletContext.getResourceAsStream("文件路径");
通过响应头的getOutputStream() 获取响应输出流
OutputStream outputstream = resp.getOutputStream();
使用IO工具类来输出
IOUtils.copy(resourceStream,outputStream);
完整代码:
package com.teen.JSPTest0729;
import org.apache.commons.io.IOUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* @author teen
* @create 2021/7/29 18:38
*/
public class FileOutputServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件名
String fileName = "微信1.jpg";
//获取上下文对象
ServletContext servletContext = getServletContext();
//通过上下文对象获取文件类型
String mimeType = servletContext.getMimeType("/微信1.jpg");
System.out.println(mimeType);
//通过响应头告诉浏览器文件类型
resp.setContentType(mimeType);
//告诉浏览器此文件为下载附件
//对中文名进行utf-8加密
String fileHeader = "attachment;fileName =" + URLEncoder.encode("微信1.jpg","UTF-8");
// String fileHeader = "attachment; fileName =微信1.jpg";
resp.setHeader("Content-Disposition",fileHeader);
//获取上下文输入流getResourceAsStream
InputStream resourceStream = servletContext.getResourceAsStream("/微信1.jpg");
//设置响应输出流
OutputStream outputStream = resp.getOutputStream();
//使用IO工具类进行输出操作
IOUtils.copy(resourceStream,outputStream);
System.out.println("已将响应发送回客户端");
}
}