当前位置: Jsp教程 > servle案例 > 阅读正文

servlet文件上传

2021.4.18.   841 次   4288字

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中, 不需要时手动删除即可.

本篇完,还有疑问?

加入QQ交流群:11500065636 IT 技术交流群