文件上传下载

本文详细介绍了在Web应用中实现文件上传和下载的功能。文件上传使用了multipart/form-data表单提交,通过Servlet处理文件上传请求,将文件保存到服务器。文件下载则通过设置响应头实现,根据不同的浏览器设置不同的编码方式。文章还提醒注意文件上传的安全性和资源管理,提供了简单的文件下载链接示例。
摘要由CSDN通过智能技术生成

大家好呀,我是小笙!

web 应用常用功能 -文件上传下载

文件上传

文件上传下载需要使用到两个包 , 需要导入

image-20220512235336933

表单提交

<!-- 表单的 enctype 属性要设置为 multipart/form-data -->
<!-- 表单默认为url编码是用来传输文本的,文件(二进制数据)需要另外一种编码方式来提交,因此是multipart分多个部分提交-->
<form action="xxxx" method="POST" enctype="multipart/form-data">
    家居图: <img src="2.jpg" alt="" width="200" height="200" id="prevView"> 
    <input type="file" name="pic" id="" value="2xxx.jpg" onchange="prev(this)"/>
    家居名: <input type="text" name="name"><br/> 
    <input type="submit" value="上传"/>
</form>

获取文件上传请求

  1. 判断表单类型(multipart/form-data或者application/x-www-form-urlencoded)
  2. 假设是multipart/form-data类型
    1. 判断表单内的数据,是普通文本的表单项,则以文本形式处理
    2. 如果是文件表单项,则使用IO流保存到本地服务器的指定目录
  3. application/x-www-form-urlencoded类型则统一都用url解码来处理

代码示例

image-20220513195142871

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <base href="<%=request.getContextPath()+"/"%>>">
    <style type="text/css"> input[type="submit"] {
        outline: none;
        border-radius: 5px;
        cursor: pointer;
        background-color: #31B0D5;
        border: none;
        width: 70px;
        height: 35px;
        font-size: 20px;
    }

    img {
        border-radius: 50%;
    }

    form {
        position: relative;
        width: 200px;
        height: 200px;
    }

    input[type="file"] {
        position: absolute;
        left: 0;
        top: 0;
        height: 200px;
        opacity: 0;
        cursor: pointer;
    } </style>
    <script type="text/javascript">
        function prev(event)
        {
            // 获取展示图片的区域
            var img = document.getElementById("prevView");
            // 获取文件对象
            let file = event.files[0];
            // 获取文件阅读器
            let reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function ()
            {
                // 给img的src设置图片url
                img.setAttribute("src", this.result);
            }
        }
    </script>
</head>
    <body>
        <!-- 表单的 enctype 属性要设置为 multipart/form-data -->
        <form action="fileServlet" enctype="multipart/form-data" method="post">
            家居图: <img src="2.jpg" alt="" width="200" height="200" id="prevView">
            <input type="file" name="pic" id="" value="2xxx.jpg" οnchange="prev(this)"/><br>
            家居名: <input type="text" name="name"><br/><br/>
            <input type="submit" value="上传"/>
        </form>
    </body>
</html>
// 工具类
public class Date {
    public static String getLocalDate(){
        LocalDateTime localDate = LocalDateTime.now();
        return String.valueOf(localDate.getYear()) + "-" + String.valueOf(localDate.getMonth())
                + "-" + String.valueOf(localDate.getDayOfMonth());
    }
}

// 文件下载类
@WebServlet(name = "FileUpload",urlPatterns = {"/fileServlet"})
public class FileUpload extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 判断请求格式是否是文件格式的
        if(ServletFileUpload.isMultipartContent(request)){
            System.out.println("文件传输");
            // 创建DiskFileItemFactory对象,用于构建一个解析上传数据的工具对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            // 创建一个解析上传数据的工具对象
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            servletFileUpload.setHeaderEncoding("utf-8");
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);
                // 遍历文件项
                for (FileItem fileItem : list) {
                    String name;
                    if(!fileItem.isFormField()){
                        // 文件名
                        name = fileItem.getName();

                        // 指定图片保存的路径
                        String filePath = getServletContext().getRealPath("/images/" + Date.getLocalDate() + "/");

                        File file = new File(filePath);
                        // 该文件目录是否存在
                        if(!file.exists()){
                            file.mkdirs();
                        }

                        // 将文件数据存入到指定目录,同时通过UUID来确定文件不会重名
                        name = UUID.randomUUID().toString() + name;
                        fileItem.write(new File(filePath + name));
                        // 页面显示
                        response.setContentType("text/html;charset=utf-8");
                        response.getWriter().write("<h1>上传成功!</h1>");
                    }else{
                        name = fileItem.getString("utf-8");
                        System.out.println(name);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("普通文本传输");
        }
    }
}

注意事项

  • 一个完美的文件上传,要考虑的因素很多,比如断点续传、控制图片大小,尺寸,分片 上传,防止恶意上传等,在项目中,可以考虑使用 WebUploader 组件
  • 文件上传功能,在项目中建议有限制的使用,一般用在头像、证明、合同、产品展示等, 如果不加限制,会造成服务器空间被大量占用

文件下载

image-20220513231844910

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件下载</title>
        <base href="<%=request.getContextPath()+"/"%>>">
    </head>
    <body>
        <h1>文件下载</h1>
        <a href="download?dir=/imgs/&resource=1.png">点击下载java图片</a><br/>
        <a href="download?dir=/word/&resource=2.doc">点击下载罗念笙笔记.doc</a>
    </body>
</html>

image-20220513232217928

@WebServlet(name = "Download",urlPatterns = {"/download"})
public class Download extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取下载的文件名字
        request.setCharacterEncoding("utf-8");
        String dir = request.getParameter("dir");
        String fileName = request.getParameter("resource");
        System.out.println(fileName);
        String resourcePath = dir + fileName;

        // 给http响应设置响应头 Content-Type
        ServletContext servletContext = request.getServletContext();
        String mimeType = servletContext.getMimeType(resourcePath);
        response.setContentType(mimeType);
        // 给http响应设置响应头 Content-Disposition
        // 针对不同的浏览器对于下载的编码方式是不一样的
        // Content-Disposition 是指定下载的数据的展示形式 , 如果attachment 则使用文件下载方式
        if(request.getHeader("User-Agent").contains("Firefox")){
            // 火狐 Base64编码
        }else {
            // 其他(主流ie/chrome)使用URL编码操作
            response.setHeader("Content-Disposition", "attachment; filename=" +
                               URLEncoder.encode(fileName, "UTF-8"));
        }
        // 读取数据io流
        InputStream resourceAsStream = servletContext.getResourceAsStream(resourcePath);
        // 通过输出流输出
        ServletOutputStream outputStream = response.getOutputStream();
        // 通过IO工具类将读取到的文件输出
        IOUtils.copy(resourceAsStream,outputStream);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗念笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值