在浏览器上实现文件上传

实现以下文件上传

要实现一个文件的上传

  1. 请求的方式必须是post
  2. 必须要设置 enctype=“multipart/form-data” (设置分割线)
    表单的提交的时候会分成多个部分提交,多个部分之间使用分割线来分割
  3. 选择文件必须要使用file

jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="<%=request.getContextPath()%>/upload" method="post" enctype="multipart/form-data">
    <input type="text" name="username"><br>
    <input type="file" name="fileupload"><br>
    <input type="submit" value="Submit">
  </form>
  </body>
</html>

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 org.apache.commons.io.IOUtils;

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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

// 演示文件上传的Servlet
@WebServlet("/upload")
public class FileUploadServlet extends HttpServlet {

    // 要接收文件上传的信息,必须要使用post类型的请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // commons-fileupload 接收文件
        // 1) 创建FileItem操作工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 2) 创建一个解析类
        //    解析表单中多部分提交的内容(按照分割线解析)
        ServletFileUpload sfu = new ServletFileUpload(factory);
        try {
            // 3) 解析请求
            List<FileItem> fileItems = sfu.parseRequest(req);
            // 4) 迭代FileItem
            //  每一个FileItem对象都表示表单的一项内容
            for (FileItem fileItem : fileItems) {
                // 5) 区分表单的普通项还是上传项
                if (fileItem.isFormField()) { // 判断当前的表单项是不是一个普通项
                    // true: 就是一个普通项
                    // 普通项打印到控制台上
                    String fieldName =fileItem.getFieldName(); // 获取普通项的参数名称
                    String fieldValue = fileItem.getString(); // 获取普通项的参数值
                    // 就算是设置了过滤器,提交中文一样会出现乱码的情况
                    // 需要手动解码
                    // 先将数据转化成 ISO-8859-1的字符串 , 在转化成UTF-8的字符集
                    String result = new String(fieldValue.getBytes("ISO-8859-1"), "UTF-8");
                    System.out.println("fieldName:" + fieldName + " fieldValue:" + fieldValue + " result: " + result);
                } else {
                    // 就是一个上传项
                    // 上传项保存到硬盘上

                    // 获取文件的名称
                    String filename = fileItem.getName();
                    // 获取文件的输入流
                    InputStream inputStream = fileItem.getInputStream();

                    // 给硬盘上写数据

                    // 接下来要完成的功能 , 就是将上传的文件放到当前项目的输入目录下
                    String realPath = super.getServletContext().getRealPath("upload"); // 获取当前项目的输出目录(硬盘目录)
                    // 判断目录是否存在 , 不存在则创建一下目录
                    File dir = new File(realPath);
                    // dir.exists()判断目录或文件是否存在  true:表示文件或目录已经存在 false:不存在
                    if (dir.exists() == false) {
                        // 创建一下目录
                        dir.mkdirs();
                    }
                    // 生成文件的绝对路径
                    String newFileName = realPath + "/" + filename; // 新的硬盘目录 + 上传文件的名称
                    System.out.println("newFileName: " + newFileName);
//                    方式一: 写如到固定的目录下
//                    String dstDir = "D:\\fileupload"; // 目标输入目录
//                    String dstFile = dstDir + "/" + filename; // 生成文件的输出目录
//                    // 实现流复制   将输入流的数据  写入到输出流内
//                    try (FileOutputStream out = new FileOutputStream(dstFile)) {
//                        IOUtils.copy(inputStream, out);
//                    }

                    // 方式二: 上传的文件生成到项目的发布目录下
                    // 实现流复制   将输入流的数据  写入到输出流内
                    try (FileOutputStream out = new FileOutputStream(newFileName)) {
                        IOUtils.copy(inputStream, out);
                    }
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

    }
}

文件上传的注意事项:

1) 要对文件的名称进行重新命名,否则可能会导致文件名重复

​ UUID 每秒生成在1千万以下 是不会重复的 , 每秒生成在1千万以上 有一定概率会重复 (概率很低)

​ 我: avator.jpg -> {UUID}.jpg

​ 小明: avator.jpg -> {UUID}.jpg

2) 上传文件要放在不同的目录下

​ Linux 对单个文件夹下的文件数量有要求 通常是不会大于 65535个文件

​ 可以通过专业运维解除这个限制

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值