文件上传

跟着书上的例子写了个文件上传的简单页面,感觉还蛮有意思的

前端

要上传文件,必须利用multipart/form-data设置HTML表单的enctype属性。

<form action="action" method="post" enctype="multipart/form-data">
    Select a file <input type="file" name="fieldName" /> 这个fieldName必须设置

服务器端

通过MultipartConfig注解类型和javax.servlet.http.Part接口进行处理,处理上传文件的Servlet必须用@MultipartConfig进行标注
MultipartConfig有以下可选属性

  1. maxFileSize,表示最多可上传的文件容量,默认值-1。
  2. maxRequestSize,表示允许多部分HTTP请求的最大容量,默认值为-1
  3. location,指定上传的文件保存到磁盘中的指定位置
  4. fileSizeThreshold,设定一个溢出尺寸,超过这个值的文件将被临时存储在磁盘

HttpServletRequest 接口定义了以下方法来处理多部分的请求

  1. Part getPart(String name),返回与指定名称相关的Part,这个name与前端页面中input的name相同。
  2. Collection<Part> getParts(),返回所有Part
  3. String getContentType(),如果Part是一个文件,返回Part的内容类型,否则返回null
  4. Collection<String> getHeaderNames(),返回这个Part中的所有header名称
  5. void write(String path),将文件写入指定的路径
  6. void delete(),删除该文件对应的存储,包括相关的临时文件
  7. InputStream getInputStream(),以流形式返回上传文件的内容

域的形式

如果上传域中有一个名为document的note.txt文件时,产生的header

content-type:text/plain
content-disposition:form-data; name="document"; filename="note.txt"

如果是一个非文件的域,Part将只有content-disposition的header
格式:content-disposition:form-data; name="fiedlName"

范例

@WebServlet(urlPatterns = "/singleUpload")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 3, maxFileSize = 1024 * 1024 * 10)
public class UploadFileServlet extends HttpServlet {

    private static final long serialVersionUID = 8593039L;

    /**
     * 从Part中提取文件名
     * @param part
     * @return
     */
    private String getFileName(Part part) {
        String contentDispositionHeader = part.getHeader("content-disposition");
        String[] elements = contentDispositionHeader.split(";");
        for (String element : elements) {
            if (element.trim().startsWith("filename")) {
                return element.substring(element.indexOf('=') + 1).trim().replace("\"", "");
            }
        }

        return null;
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Part part = req.getPart("filename");
        String filename = getFileName(part);
        
        if (filename != null && !filename.isEmpty()) { //检测文件名是否合法
            
            // 在WEB-INF目录下创建/tmp/upload/文件夹,将上传文件存储到这个文件夹下
            // WEB-INF目录下的文件是无法通过链接直接访问的
            File f = new File(getServletContext().getRealPath("/WEB-INF") + "/tmp/upload/");
            if (!f.exists()) {
                f.mkdirs();
            }
            
            // 将文件写入
            part.write(getServletContext().getRealPath("/WEB-INF") + "/tmp/upload/" + filename);

        }

        
        // 返回文件的名字,大小,上传者等信息
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.print("<br/>Upload file name: " + filename);
        writer.print("<br/>Size: " + part.getSize());

        String author = req.getParameter("author");
        writer.print("<br/>Author: " + author);
        writer.close();
    }

}

再来看下前端页面singleUpload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Select a file to upload</h1>
    <form action="singleUpload" enctype="multipart/form-data", method="post">
        Author: <input type="text" name="author" /><br/>
        <!-- 这里name的值“filename”在获取Part对象时使用 -->
        Select file to upload <input type="file" name="filename" /> <br/>
        <input type="submit" value="Upload">
    </form>
</body>
</html>
页面

点击上传就可以在配置的文件夹下看到自己上传的文件了。

总结

这篇博客只是实现了一个很简单的文件上传,算是给自己的后端之路挖下第一个坑(???)一直感觉后端很高大上,第一次动手写东西果然高大上hhhhh,Android里没怎么使用到的注解啊,文件,IO流都在这里得到了较多使用,很神奇的感觉(手动捂脸)。希望能慢慢学点后端知识吧。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 121,758评论 17 134
  • 一、文件上传概述 实现web开发中的文件上传功能,需完成如下二步操作在web页面中添加上传输入项在servlet中...
    yjaal阅读 2,287评论 0 23
  • 文件上传 文件上传是一个常用的功能。同时也是非常难以掌握的一个技术部分。这篇文章从前后端两个部分来分析要完成一个文...
    LeoMelody阅读 34,427评论 1 6
  • 近日,读完《卓有成效的管理者》,收获了15个道理。 1、 管理者所做的工作必须要有效,即按时做完该做的事。 2、 ...
    品牌张阅读 242评论 0 0
  • 文|迷诗先生 我的心里 有座小城 小城很大 能容万人 小城很小 装不下你一个
    迷诗先生阅读 114评论 23 5