servlet实现文件上传, 通常使用 fileUpload 组件, 这是apache封装的开源工具jar包
下载jar包
对于 maven 项目, 导入如下坐标
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
commons-fileupload.jar依赖于commons-io.jar, 所以这2个jar包都需要下载
如果要直接下载jar包, 可以拷贝上述地址在 maven 中央仓库下载, 或者apache官网下载, 这里提供一个备份下载
前端代码
前端可以通过 form 表单提交文件, 按照官网的说法, 实现方法如下:
- 必须是post方式
- 通过input上传, 其中type是file, 而name是spicture
- form中, 必须添加一个属性 enctype=”multipart/form-data”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>servlet文件上传测试</title>
</head>
<body>
<h2>把action的路径换成真实路径再测试</h2>
<form action="/xxx/UploadServlet" method="post" enctype="multipart/form-data">
学号:<input type="text" name="sno"/><br/>
姓名:<input type="text" name="sname"/><br/>
上传照片:<input type="file" name="spicture"/><br/>
<input type="submit" value="提交" />
</form>
</body>
</html>
后端代码
后端是一个servlet, 应该监听 post, 如果是jsp页面, 那么需要判断request.getmethod是否为post
import org.apache.commons.fileupload.FileItem;
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.ServletException;
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.List;
@WebServlet(name = "UploadServlet", urlPatterns = "/UploadServlet")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码和mime
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//2.判断表单是否存在文件
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
response.getWriter().println("存在上传文件<br>");
//3.生成upload对象, 获取上传字段
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024*10);
factory.setSizeThreshold(1024*5); //设置单个缓冲文件大小
File tempFile = new File("temp");
if (!tempFile.exists()){
tempFile.mkdir(); //创建此文件夹
}
factory.setRepository(new File("temp"));//设置缓冲文件的位置
List<FileItem> items = null;
try {
items = upload.parseRequest(request); //获取参数所有的参数字段
}catch(FileUploadBase.SizeLimitExceededException e){
System.out.println("文件大小超过限制,必须是10kb以下");
response.getWriter().write("文件大小超过限制, 必须是10kb以下<br>");
return;
}catch (FileUploadException e) {
e.printStackTrace();
}
//4.判断该字段是file字段, 还是普通的表单字段
for(FileItem item : items){
if(item.isFormField()){ //是普通字段
if(item.getFieldName().equals("sno"))
{
String sno = item.getString(); //获取学号
System.out.println("学号是:"+sno);
}else if (item.getFieldName().equals("sname")){
String sname = item.getString("UTF-8");//获取姓名
System.out.println("姓名是:"+sname);
}
}else{ //是文件字段spicture
//5.上传文件
String fileName = item.getName(); //这个名称是form提交的字段, ie可能是绝对路径
//5.1限制文件类型
boolean canUpload = false;
if(fileName.endsWith(".jpg")||fileName.endsWith("png")){
canUpload = true;
}else{
System.out.println("上传类型错误,仅支持jpg或png");
response.getWriter().write("上传类型错误,仅支持jpg或png<br>");
return; //终止上传
}
File uploadFile = new File("uploads");
if(!uploadFile.exists()){
uploadFile.mkdir();
}
String path = uploadFile.getAbsolutePath();//上传保存的文件夹
File file = new File(path,fileName);
try {
item.write(file); //上传
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(fileName+"上传成功");
response.getWriter().print(fileName+"上传成功!");
return;
}
}
}else{
//没有上传的文件
response.getWriter().println("您没有选择上传文件");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
}
}
限制文件类型和大小
对文件类型以及文件大小, 可以用前端或后端限制, 前端可以用js判断
1.限制文件类型
在获取文件名后, 使用 .endwith 判断文件名是否以 xxx为后缀, 此时就能够判断到文件的后缀了
一旦文件后缀不符合, 那么就终止上传并返回错误
2.限制文件大小
使用 upload 对象的 setSizeMax() 方法, 其中单位是b, 比如要设置 10KB, 那么大小为 setSizeMax(1024*10);
此字段应该放在解析form字段之前, 否则不起作用
可以捕获一个 FileUploadBase.SizeLimitExceededException, 即文件大小超过最大限制的错误.
3.此外, 还可以设置上传文件的缓冲大小和目录
factory.setSizeThreshold(1024*5); //单个缓冲文件大小5kb
factory.setRepository("uploadtemp"); //设置缓冲目录
限制代码默认已添加在 uploadServlet中, 不需要时手动删除即可.