springboot multipart/form-data;文件上传请求组装

本文介绍如何在SpringBoot项目中实现multipart/form-data类型的文件上传请求。通过自定义FileFormData类,详细解析了请求体的组装过程,包括分隔符、参数和文件流的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot multipart/form-data;文件上传请求组装

工作需要后台上传文件。自行组装文件上传类

form-data 文件的基本形式
  • 1、请求体需分隔符:-----------------------------152909417026772332233306781192来组装。一个分隔符下一个请求参数。分隔符是随机的。
  • 2、最后一个参附上文件描述和文件的字节流
  • 3、以分隔符加--标记结尾: -----------------------------152909417026772332233306781192--
/**
 * ========================   请求体范例    ===========================
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="type"
 *
 * image
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="app_id"
 *
 * 1643192118890183
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="is_waterlog"
 *
 * 1
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="save_material"
 *
 * 1
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="no_compress"
 *
 * 0
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="is_events"
 *
 *
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="article_type"
 *
 * news
 * -----------------------------152909417026772332233306781192
 * Content-Disposition: form-data; name="media"; filename="timg.jpeg"
 * Content-Type: image/jpeg
 *
 * {这里是文件流}
 * -----------------------------152909417026772332233306781192--
 */
代码

import org.apache.http.util.ByteArrayBuffer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 请求中  form-data 的抽象
 */
public class FileFormData {

    private static final String ENCODE = "utf-8";
    //分隔符号
    private static String delimiter = "7dc641c2e0260";
    //自定body
    private static HashMap<String, String> paramMap;
    //文件body参数
    private static String fileFiledName;
    private static String fileName;
    private static String fileType;
    private static String fileUrl;

    /**
     *
     * @param fileFiledName 表单文件部分的filedname:    Content-Disposition: form-data; name="{fileFiledName}"; filename="timg.jpeg"
     * @param fileName      表单文件部分的filename:     Content-Disposition: form-data; name="{fileFiledName}"; filename="{fileName}"
     * @param fileType      表单文件部分的content-type: Content-Type: {fileType}
     * @param fileUrl       文件资源定位符
     */
    public FileFormData(String fileFiledName, String fileName, String fileType, String fileUrl){
        paramMap = new HashMap<>();
        FileFormData.fileFiledName = fileFiledName;
        FileFormData.fileName = fileName;
        FileFormData.fileType = fileType;
        FileFormData.fileUrl = fileUrl;

    }
    public static String getDelimiter() {
        return delimiter;
    }

    /**
     * 分隔符设定。需指定分隔符时使用
     * @param delimiter
     */
    public static void setDelimiter(String delimiter) {
        FileFormData.delimiter = delimiter;
    }

    /**
     * 获取header contextType 一般是默认的。只需覆盖header就行。
     * 但如果特殊平台检测上传分隔符, 则需先设置 特有的分隔符
     * 其他关键参数默认随之生成
     * context-type: multipart/form-data;boundary=---------------------------{delimiter}
     * 分隔符: -----------------------------{delimiter}\r\n
     * 终止符: -----------------------------{delimiter}--\r\n
     * @param delimiter
     */
    public String getHeaderContextType(String delimiter) {
        FileFormData.delimiter = delimiter;
        return  "multipart/form-data; boundary=---------------------------" + FileFormData.delimiter;
    }

    String getHeaderContextType() {
        return  "multipart/form-data; boundary=---------------------------" + FileFormData.delimiter;
    }
    public void put(String key, String val){
        paramMap.put(key, val);
    }
    byte[] getFormDataBody() throws IOException {
        String delimiter = "-----------------------------"+ FileFormData.delimiter +"\r\n";
        String over = "-----------------------------"+ FileFormData.delimiter +"--\r\n";

        //自定参数组装
        ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(10);
        for (Map.Entry<String, String> param : paramMap.entrySet()) {
            if (!((param.getKey() == null) || (param.getKey().length() == 0))) {
                byte[] headByte = delimiter.getBytes(ENCODE);
                byteArrayBuffer.append(headByte, 0, headByte.length);
                String textTemplate = "Content-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n";
                String text = String.format(textTemplate, param.getKey(), param.getValue());
                byte[] textByte = text.getBytes(ENCODE);
                byteArrayBuffer.append(textByte, 0, textByte.length);
            }
        }
        //当传入的fileType为空时 获取content-type
        if(FileFormData.fileType.equals("")){
            FileNameMap fileNameMap = URLConnection.getFileNameMap();
            FileFormData.fileType = fileNameMap.getContentTypeFor(fileUrl);
            System.out.println("file type:"+FileFormData.fileType);
        }

        //文件参数组装
        String end = "\r\n";
        String textTemplate = "Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n";
        textTemplate += "Content-Type: %s\r\n\r\n";
        String fileFormHeadStr = String.format(textTemplate, fileFiledName, fileName, fileType);
        byte[] headBytes = fileFormHeadStr.getBytes(ENCODE);
        byte[] fileDatas = null;
        byte[] endBytes = end.getBytes(ENCODE);
        // over 是最重的终止符号,终止后整个请求body组装完毕
        byte[] overBytes = over.getBytes(ENCODE);

        //加载文件的字节流
        URL url = new URL(FileFormData.fileUrl);
        URLConnection con = url.openConnection();
        InputStream is = con.getInputStream();

        if (is == null) return new byte[0];
        fileDatas = StreamUtil.convertToBytes(is);
        ByteArrayOutputStream totals = new ByteArrayOutputStream();
        totals.write(byteArrayBuffer.toByteArray());
        totals.write(delimiter.getBytes(ENCODE));
        totals.write(headBytes);
        if (fileDatas != null) {
            totals.write(fileDatas);
        } else {
            totals.close();
            return new byte[0];
        }
        totals.write(endBytes);
        totals.write(overBytes);
        byte[] resTotals = totals.toByteArray();
        totals.close();
        System.out.println(totals.toString());
        return resTotals;
    }
}

使用范例
FileFormData postForm = new FileFormData("media","abc.jpg", "image/jpeg", "图片的完整可访问路径");
		  postForm.put("type","image");
		  postForm.put("666","666");
		  postForm.put("777","777");
		 String url = "上传地址";
		 byte[] body = postForm.getFormDataBody();
		 //header 自定
		 //将body作为请求体发起请求即可。

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值