文件上传

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

前端

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

Select a file 这个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 getParts(),返回所有Part
  3. String getContentType(),如果Part是一个文件,返回Part的内容类型,否则返回null
  4. Collection 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("
Upload file name: " + filename); writer.print("
Size: " + part.getSize()); String author = req.getParameter("author"); writer.print("
Author: " + author); writer.close(); } }

再来看下前端页面singleUpload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

Select a file to upload

Author:
Select file to upload
文件上传_第1张图片
页面

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

总结

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

你可能感兴趣的:(文件上传)