您的位置 首页 java

Java,Servlet,Apache FileUpload组件,处理表单上传/文件上传

Web文件上传

RFC1867协议:

RFC1867主要是在HTTP协议的基础上为INPUT标签增加了file属性,同时限定了Form的method必须为POST,ENCTYPE必须为multipart/form-data。

表单上传协议:

 POST /web/upload.html HTTP/1.1
header-name: header-value
User-Agent: MyBrowser
Host: 127.0.0.1:9090
Proxy-Connection: Keep-Alive
Content-Length: 5989
Content-Type: multipart/form-data; boundary=----------------314159265358979323846
 
------------------314159265358979323846
Content-Disposition: form-data; name="file1"; filename="logo.gif"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
 
--二进制内容(略)
 
------------------314159265358979323846
Content-Disposition: form-data; name="file2"; filename="logo.png"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
 
--二进制内容(略)
 
------------------314159265358979323846--  

服务器端Servlet + Apache FileUpload实现

pom.xml

 <!-- 上传文件 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>  

Servlet类

 package com.what21.servlet.upload;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.what21.servlet.upload.helper.HttpServletUploadHelper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

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.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebServlet("/upload/form")
public class FormUploadServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("code", "ok");
        // ===================================================================================//
        // ===== 处理&保存文件
        // ===================================================================================//
        String tmpDir = "D:/Temp/Upload/tmp"; // 临时目录
        String domain = "";  // 域
        String function = "head";  // 功能
        String storagePath = "D:/Temp/Upload/"; // 上传目录
        List<HttpServletUploadHelper.Entity> entityList = null;
        try {
            List<FileItem> fileItemList = HttpServletUploadHelper.toFileItems(request, tmpDir, "UTF-8");
            entityList = HttpServletUploadHelper.parseToEntitys(fileItemList, storagePath, domain, function);
            dataMap.put("data", entityList);
        } catch (Exception e) {
            e.printStackTrace();
            dataMap.put("code", "error");
            dataMap.put("msg", e.getMessage());
        }
        // ===================================================================================//
        // ===== 返回结果
        // ===================================================================================//
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(dataMap);
        response.setContentType("text/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        writer.print(json);
        writer.flush();
    }

}
  

工具类

 package com.what21.servlet.upload.helper;

import com.relops.snowflake.Snowflake;
import lombok.Data;
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.FileCleanerCleanup;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileCleaningTracker;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public final class HttpServletUploadHelper {

    // ===================================================================================//
    // ===== header中操作
    // ===================================================================================//

    /**
     * 从header中获取值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */    public static String getHeaderValue(HttpServletRequest request, String name, String defaultValue) {
        String value = request.getHeader(name);
        if (StringUtils.isNotEmpty(value)) {
            return value;
        }
        return defaultValue;
    }

    // ===================================================================================//
    // ===== 文件操作
    // ===================================================================================//

    /**
     * 获取文件后缀
     *
     * @param name
     * @return
     */    public static String getFileSuffix(String name) {
        if (StringUtils.isNotEmpty(name)) {
            if (name.contains(".")) {
                return name.split("\.")[1];
            }
        }
        return "";
    }

    /**
     * 交换保存
     *
     * @param inputStream
     * @param filename
     * @throws IOException
     */    public static File exchangeSave(InputStream inputStream, String filename) throws IOException {
        File saveFile = new File(filename);
        if (!saveFile.getParentFile().exists()) {
            saveFile.getParentFile().mkdirs();
        }
        FileOutputStream output = new FileOutputStream(filename);
        int r = -1;
        byte[] bytes = new byte[512];
        while ((r = inputStream.read(bytes)) != -1) {
            output.write(bytes, 0, r);
        }
        output.flush();
        output.close();
        return saveFile;
    }

    // ===================================================================================//
    // ===== 实体操作
    // ===================================================================================//

    /**
     * 从header中取参数
     *
     * @param request
     * @param domain
     * @param function
     * @return
     * @throws IOException
     */    public static Entity createEntityWithHeader(HttpServletRequest request, String domain, String function) throws IOException {
        Entity entity = new Entity();
        entity.setId(getSnowflakeId());
        entity.setModular(HttpServletUploadHelper.getHeaderValue(request, "modular", "communal"));
        entity.setModel(HttpServletUploadHelper.getHeaderValue(request, "model", "common"));
        entity.setName(HttpServletUploadHelper.getHeaderValue(request, "name", getRandomString(30)));
        entity.setType(HttpServletUploadHelper.getHeaderValue(request, "type", "file"));
        entity.setSuffix(HttpServletUploadHelper.getFileSuffix(entity.getName()));
        entity.setFile(entity.getId() + "." + entity.getSuffix());
        String accessAddress = "/" + entity.getModular() + "/" + entity.getModular();
        String storageAddress = "/" + entity.getModular() + "/" + entity.getModular();
        if (StringUtils.isNotEmpty(domain)) {
            accessAddress = domain + "/" + accessAddress;
            storageAddress = domain + "/" + storageAddress;
        }
        if (StringUtils.isNotEmpty(function)) {
            accessAddress = accessAddress + "/" + function;
            storageAddress = storageAddress + "/" + function;
        }
        accessAddress = accessAddress + "/" + entity.getId();
        storageAddress = storageAddress + "/" + entity.getId();
        entity.setAccessAddress(accessAddress);
        entity.setStorageAddress(storageAddress);
        entity.setStatus(0);
        return entity;
    }

    // ===================================================================================//
    // ===== 实体类
    // ===================================================================================//

    @Data
    public static class Entity {

        // 主键ID
        private Long id;

        // 系统一级模块
        private String modular;

        // 系统二级模块
        private String model;

        // 静态资源名称
        private String name;

        // 静态资源类型
        private String type;

        // 静态资源文件
        private String file;

        // 文件大小
        private Long size;

        // 静态资源后缀
        private String suffix;

        // 静态资源状态
        private Integer status;

        // 资源存储地址
        private String storageAddress;

        // 资源访问地址
        private String accessAddress;

    }

    // ===================================================================================//
    // ===== 工具操作
    // ===================================================================================//

    /**
     * @return
     */    public static Long getSnowflakeId() {
        return getSnowflakeId(1);
    }

    /**
     * @param node
     * @return
     */    public static Long getSnowflakeId(int node) {
        Snowflake snowflake = new Snowflake(node);
        return snowflake.next();
    }

    /**
     * 获取随机字符串
     *
     * @param length
     * @return
     */    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    // ===================================================================================//
    // ===== 表单上传
    // ===================================================================================//

    /**
     * @param request
     * @param tmpDir
     * @param encode
     * @return
     * @throws FileUploadException
     */    public static List<FileItem> toFileItems(HttpServletRequest request, String tmpDir, String encode) throws FileUploadException {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 重新设置临时文件保存目录
        factory.setRepository(new File(tmpDir));
        // 设置文件清除追踪器,文件上传过程中产生的临时文件
        FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(request.getServletContext());
        factory.setFileCleaningTracker(fileCleaningTracker);
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置字符编码UTF-8
        upload.setHeaderEncoding(encode);
        // 解析请求数据包
        return upload.parseRequest(request);
    }

    /**
     * @param fileItemList
     * @param storagePath
     * @param domain
     * @param function
     * @return
     * @throws IOException
     */    public static List<Entity> parseToEntitys(List<FileItem> fileItemList, String storagePath, String domain, String function)
            throws IOException {
        List<Entity> entityList = new ArrayList<>();
        // ===================================================================//
        // =====模块化参数
        // ===================================================================//
        String modular = "communal";
        String model = "common";
        for (FileItem fileItem : fileItemList) {
            String fieldName = fileItem.getFieldName();
            if (fileItem.isFormField()) {
                if ("modular".equals(fieldName)) {
                    modular = fileItem.getString();
                } else if ("model".equals(fieldName)) {
                    model = fileItem.getString();
                }
            }
        }
        // ===================================================================//
        // =====地址处理
        // ===================================================================//
        String accessAddress = "/" + modular + "/" + model;
        String storageAddress = "/" + modular + "/" + model;
        if (StringUtils.isNotEmpty(domain)) {
            accessAddress = domain + "/" + accessAddress;
            storageAddress = domain + "/" + storageAddress;
        }
        if (StringUtils.isNotEmpty(function)) {
            accessAddress = accessAddress + "/" + function;
            storageAddress = storageAddress + "/" + function;
        }
        // ===================================================================//
        // =====保存并构建对象
        // ===================================================================//
        for (FileItem fileItem : fileItemList) {
            String name = fileItem.getName();
            if (!fileItem.isFormField() && fileItem.getSize() > 0) {
                // 文件后缀
                String fileExtension = FilenameUtils.getExtension(name);
                // 文件名
                String fileName = FilenameUtils.getName(name);
                Entity entity = new Entity();
                entity.setId(getSnowflakeId());
                entity.setModular(modular);
                entity.setModel(model);
                entity.setName(fileName);
                entity.setType(fileItem.getContentType());
                entity.setSuffix(fileExtension);
                entity.setFile(entity.getId() + "." + fileExtension);
                entity.setSize(fileItem.getSize());
                entity.setStatus(0);
                entity.setAccessAddress(accessAddress + "/" + entity.getId());
                entity.setStorageAddress(storageAddress + "/" + entity.getId());
                // 保存文件
                File saveFile = new File(storagePath + entity.getStorageAddress());
                if (!saveFile.getParentFile().exists()) {
                    saveFile.getParentFile().mkdirs();
                }
                FileUtils.copyInputStreamToFile(fileItem.getInputStream(), saveFile);
                entityList.add(entity);
            }
        }
        return entityList;
    }

    // ===================================================================================//
    // ===== The end
    // ===================================================================================//


}  

上传文件客户端测试

Postman测试

结果

 {
    "code": "ok",
    "data": [
        {
            "id": 6905426757113876480,
            "modular": "modular01",
            "model": "model01",
            "name": "001.jpg",
            "type": "image/jpeg",
            "file": "6905426757113876480.jpg",
            "size": 4473,
            "suffix": "jpg",
            "status": 0,
            "storageAddress": "/modular01/model01/head/6905426757113876480",
            "accessAddress": "/modular01/model01/head/6905426757113876480"
        },
        {
            "id": 6905426757130653696,
            "modular": "modular01",
            "model": "model01",
            "name": "212.txt",
            "type": "text/plain",
            "file": "6905426757130653696.txt",
            "size": 1003,
            "suffix": "txt",
            "status": 0,
            "storageAddress": "/modular01/model01/head/6905426757130653696",
            "accessAddress": "/modular01/model01/head/6905426757130653696"
        }
    ]
}  

表单测试页面

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form表单上传</title>
    <script src="#34;></script>
    <link href="#34; rel="stylesheet">
</head>
<body>
    <div class="container " style="width:600px;">
        <span>
          <h1>Form表单上传</h1>
        </span>
        <form method="post" action="#34; enctype="multipart/form-data">
            <input type="hidden" name="model" value="object" />
            <div class="form-group">
                <label for="address">上传地址:</label>
                <input id="address" name="address" class="form-control" value="#34; />
            </div>
            <div class="form-group">
                <label for="modular">一级模块:</label>
                <input id="modular" name="modular" class="form-control" value="modular"/>
            </div>
            <div class="form-group">
                <label for="model">二级模块:</label>
                <input id="model" name="model" class="form-control" value="model" />
            </div>
            <div class="form-group">
                <label for="file1">上传文件1:</label>
                <input id="file1" type="file" name="file1" value="" class="form-control" />
            </div>
            <div class="form-group">
                <label for="file2">上传文件2:</label>
                <input id="file2" type="file" name="file2" value="" class="form-control" />
            </div>
            <div class="form-group">
                <label for="desc">描述:</label>
                <textarea id="desc" name="desc" class="form-control" style="min-height: 200px;"></textarea>
            </div>
            <div class="form-group form-check">
                <label class="form-check-label">
                    <input class="form-check-input" type="checkbox">记住我
                </label>
            </div>
            <button type="reset" class="btn btn-secondary">取消</button>
            <button type="submit" class="btn btn-danger">提交</button>
        </form>
    </div>
</body>
</html>  

文章来源:智云一二三科技

文章标题:Java,Servlet,Apache FileUpload组件,处理表单上传/文件上传

文章地址:https://www.zhihuclub.com/174484.shtml

关于作者: 智云科技

热门文章

网站地图