<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
使用tomcat部署项目时上传的目录有时会被删除:
如果修改代码,重新启动项目,项目会重新部署class文件
为防止上传目录丢失:a. 虚拟路径 b. 目录改为非tomcat内路径
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传和下载</title>
</head>
<body>
<center>
请输入姓名、学号和要上传的文件(只能是png、jpg、gif类型)
<div style="width:540px;border:1px solid black;background-color:#ddd">
<form action="../../UploadServlet " id="form1" name="form1" method="post" enctype="multipart/form-data" >
学号:<input type="text" name="uno" id="uno" ><br>
姓名:<input type="text" name="uname" id="uname" ><br>
上传照片:<input type="file" name="spicture" id="file"/>
<input type="submit" value="提交">
</form>
</div>
</center>
</body>
<script type="text/javascript">
function demo()
{
var name = document.getElementById("name");
var pass = document.getElementById("pass");
var file = document.form1.file.value.toString().trim().length;
var errStr = "";
if (uname.value == "" || uname.value == null)
{
errStr += "用户名不能为空\n";
}
if (uno.value == "" || uno.value == null)
{
errStr += "密码不能为空\n";
}
if (file <= 0)
{
errStr += "请选择要上传的文件\n";
}
if (errStr == "" || errStr == null)
{
return true;
}
alert(errStr);
return false;
}
document.getElementById("form1").onsubmit = demo;
</script>
</html>
UploadServlet.java
package UpAndDown;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
/**
* @Author: qsX
* @Time: 2020-05-11 10:03
* @Description: 上传的servlet
*/
@WebServlet("UploadServlet")
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=UTF-8");
try {
//上传
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
if (isMultipart) {//判断前台的form是否有mutipart属性
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//设置上传文件时的临时文件的大小 10kb 缓冲区 factory = new DiskFileItemFactory()
factory.setSizeThreshold(1024 * 10);
String uploadtemp = req.getSession().getServletContext().getRealPath("uploadtemp");
factory.setRepository(new File(uploadtemp));//设置临时文件目录
//设置上传单个文件大小 20kb upload = new ServletFileUpload(factory)
upload.setSizeMax(1024 * 20);//字节
//通过parseRequest解析form中的所有请求对象并保存到items集合中
//(即前台传递的sno sname spicture此时就保存在了items中)
List<FileItem> items = null;
items = upload.parseRequest(req);
//通过迭代器遍历items中的数据
Iterator<FileItem> iter= items.iterator();
while(iter.hasNext()) {
FileItem item = iter.next();
String itemName = item.getFieldName();
int sno = -1;
String sname = null;
//因为form中的属性enctype="multipart/form-data"所以不能用req.getParameter()
//只能用item.getString()判断匹配并赋值
if (item.isFormField()){//判断前合字段是普通form表单字段,还是文件字段
if (itemName.equals("sno")) {//根据name属性判断item是sno 还是sname 还是spicture
sno = Integer.parseInt(item.getString("utf-8"));
} else if (itemName.equals("sname")) {
sname = item.getString("utf-8");
} else {
System.out.println("其他字段");
}
} else {//文件上传
//先拿到文件名
//getFieldName是获取普通表单字段的Name值;getName()是获取文件名
String fileName = item.getName();
//通过获取文件名后缀来判断文件类型
String ext = fileName.substring(fileName.indexOf(".")+1);
if(!(ext.equals("png") || ext.equals("jpg") || ext.equals("gif"))) {
req.getRequestDispatcher("demo/UpAndDown/error.jsp").forward(req, resp);
return;//终止
}
//获取文件的内容,并上传
String path = req.getSession().getServletContext().getRealPath("upload");
//也可以写绝对路径
File file = new File(path,fileName);//指定上传的位置(服务器路径 )
item.write(file);
System.out.println(fileName+"上传成功!");
return;
}
}
}
} catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.下载文件必须设置消息头
resp.addHeader("contentType","MIME类型");
resp.addHeader("content-Disposition","attachment;filename=" + fileName);
文件类型 | Content-Type |
---|---|
二进制文件(任何类型的文件) | application/octet-stream |
Word | application/ msword |
Execl | application/vnd.ms-excel |
PPT | application/vnd.ms-powerpoint |
图片 | image/gif , |
文本文件 | text/plain |
html网页 | text/html |
jsp页面
DownloadServlet.java
package UpAndDown;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* @Author: qsX
* @Time: 2020-05-12 00:46
* @Description: 下载
*/
@WebServlet("DownloadServlet")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//获取要下载的文件名
String fileName = req.getParameter("filename");//form \ a href \...Server?a=b
//下载文件必须设置消息头
resp.addHeader("content-Type","application/octet-stream");
resp.addHeader("contentType","MIME类型");
resp.addHeader("content-Disposition","attachment;filename=" + fileName);//fileName包含了文件后缀:abc.txt
//2. Servlet通过文件的地址 , 将文件转为输入流 读到servlet中
InputStream in = getServletContext().getResourceAsStream("/upload/" + fileName);
//3. 通过输出流 将刚才转为输入流的文件输出给客户
ServletOutputStream out = resp.getOutputStream();
byte[] bs = new byte[10];
int len = -1;
while((len = in.read(bs)) != -1) {
out.write(bs,0,len);
}
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
当下载文件名为中文时可能会乱码
//当下载文件名是中文的时候可能会乱码,需要设置编码,如下
resp.addHeader("content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
前缀:
中:String构造方法(Base64.)
后缀:?=
resp.addHeader("content-Disposition","attachment;filename==?UTF-8?B?"
+ new String(Base64.getEncoder().encodeToString(fileName.getBytes("UTF-8"))) +"?=");
//判断是什么浏览器,先获取user-agent
String agent = req.getHeader("User-Agent");
if (agent.toLowerCase().indexOf("safari") != -1) {
resp.addHeader("content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
} else {
resp.addHeader("content-Disposition","attachment;filename==?UTF-8?B?"
+ new String(Base64.getEncoder().encodeToString(fileName.getBytes("UTF-8"))) +"?=");
}