当前位置:   article > 正文

【使用multipart/form-data方式传递MultipartFile参数,实现服务间文件的传递】_multipartfile前端怎么传

multipartfile前端怎么传

目录

一、代码实现

二、MultipartFile工具类

三、HttpClient使用

四、参考链接

一、代码实现
1、A服务接收前端上传文件并发送至B服务
引入依赖
  • 1
<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.13</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

使用MultipartFile接收前端文件

   @RequestMapping("/test")
    @ResponseBody
    public JSONObject getZzRxbd(HttpServletRequest request,MultipartFile file)  {
    //略
       }
  • 1
  • 2
  • 3
  • 4
  • 5

调取第三方接口,发送 MultipartFile 文件

/**
 * 以post方式调用第三方接口,以form-data 形式  发送 MultipartFile 文件数据
 *
 * @param url           post请求url
 * @param fileParamName 文件参数名称
 * @param multipartFile 文件
 * @param paramMap      表单里其他参数
 * @return 响应结果
 */
public static JSONObject doPostFormData(String url, String fileParamName, MultipartFile multipartFile, Map<String, Object> paramMap) {
    // 创建Http实例
    CloseableHttpClient httpClient = HttpClients.createDefault();
    JSONObject jsonResult = null;
    // 创建HttpPost实例
    HttpPost httpPost = new HttpPost(url);
    // 请求参数配置
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000)
            .setConnectionRequestTimeout(10000).build();
    httpPost.setConfig(requestConfig);
    try {
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setCharset(StandardCharsets.UTF_8);
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        String fileName = multipartFile.getOriginalFilename();
        // 文件流
        builder.addBinaryBody(fileParamName, multipartFile.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);
        //表单中其他参数
        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
            builder.addPart(entry.getKey(), new StringBody((String) entry.getValue(), ContentType.create("text/plain", Consts.UTF_8)));
        }
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);
        // 执行提交
        HttpResponse response = httpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 返回
            String s = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            jsonResult = JSONObject.parseObject(s);
            return jsonResult;

        }
    } catch (Exception e) {
        e.printStackTrace();
        log.error("调用HttpPost失败!" + e.toString());
    } finally {
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException e) {
                log.error("关闭HttpPost连接失败!");
            }
        }
    }
    return null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
2、B服务接收文件
@PostMapping(value = "/import", headers = "content-type=multipart/form-data")
@ApiOperation("接收上传文件")
public Result<Object> importExcel(HttpServletRequest request, HttpServletResponse response) {
    CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
    commonsMultipartResolver.setDefaultEncoding("utf-8");
    if (commonsMultipartResolver.isMultipart(request)){
        MultipartHttpServletRequest mulReq = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> map = mulReq.getFileMap();
      	// fileParamName
        MultipartFile multiFile = map.get("fileParamName");
        // 后续文件处理逻辑......
    }
    return new Result<>().error("请求内容有误!");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

二、MultipartFile工具类
简介:MultipartFile是SpringMVC提供简化上传操作的工具类,在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类。使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了。
MultipartFile工具类的接口方法

package org.springblade.common.tool;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static org.springblade.common.constant.CommonConstant.*;

/**
 * @auther: Lilei
 * @date: 2021/8/23 10:52
 */
@Slf4j
public class FileUtils {
	private static final int  BUFFER_SIZE = 2 * 1024;

	/**
     * url转MultipartFile
     */
    public static MultipartFile base64ToMultipartFile(String base64) throws Exception {
        File file = null;
        MultipartFile multipartFile = null;
        try {
        	//TODO 将base64转成字符流
			byte[] bytes = Base64.getDecoder().decode(base64);
			ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
            file = inputStreamToFile(stream,"template.png");
            multipartFile = fileToMultipartFile(file);
        } catch (Exception e) {
        	log.error(e.getMessage());
            e.printStackTrace();
        }
        return multipartFile;
    }
  	/**
     * base64转MultipartFile
     */
    public static File base64ToFile(String base64,String fliePath) throws Exception {
        File file = null;
        MultipartFile multipartFile = null;
        try {
        	// 将base64转成字符流
			byte[] bytes = Base64.getDecoder().decode(base64.replace("\r\n", ""));
			ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
            file = inputStreamToFile(stream,fliePath);
//			multipartFile = fileToMultipartFile(file);
        } catch (Exception e) {
        	log.error(e.getMessage());
            e.printStackTrace();
        }
        return file;
    }

	/**
	 * base64字符串转化成文件,可以是JPEG、PNG、TXT和AVI等等
	 *
	 * @param base64FileStr
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public static boolean generateFile(String base64FileStr, String filePath) throws Exception {
		// 数据为空
		if (base64FileStr == null) {
			System.out.println(" 不行,oops! ");
			return false;
		}
		BASE64Decoder decoder = new BASE64Decoder();


		// Base64解码,对字节数组字符串进行Base64解码并生成文件
		byte[] byt = decoder.decodeBuffer(base64FileStr);
		for (int i = 0, len = byt.length; i < len; ++i) {
			// 调整异常数据
			if (byt[i] < 0) {
				byt[i] += 256;
			}
		}
		OutputStream out = null;
		InputStream input = new ByteArrayInputStream(byt);
		try {
			// 生成指定格式的文件
			out = new FileOutputStream(filePath);
			byte[] buff = new byte[1024];
			int len = 0;
			while ((len = input.read(buff)) != -1) {
				out.write(buff, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.flush();
			out.close();
		}
		return true;
	}

  /**
     * String转MultipartFile
     */
    public static File jsonStrToFile(String json,String fliePath) throws Exception {
        File file = null;
        MultipartFile multipartFile = null;
        try {
        	//TODO 将base64转成字符流
			InputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));

            file = inputStreamToFile(stream,fliePath);
//			multipartFile = fileToMultipartFile(file);
        } catch (Exception e) {
        	log.error(e.getMessage());
            e.printStackTrace();
        }
        return file;
    }

    /**
     * file转multipartFile
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item=factory.createItem(file.getName(),"text/plain",true,file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }
   /* *//**
     * inputStream 转 File
     *//*
    public static File inputStreamToFile(InputStream ins, String name) throws Exception{
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }*/
    /**
     * inputStream 转 File
     */
    public static File inputStreamToFile(InputStream ins,String filePath) throws Exception{
        File file = new File(filePath );
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }

    /**
     * 预览视频文件
     * @param file
     * @param response
     * @throws UnsupportedEncodingException
     */
    public static void previewVideo(File file, HttpServletResponse response) throws UnsupportedEncodingException {
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            byte[] buffer = bos.toByteArray();
            response.setContentType("application/octet-stream");
            response.setHeader("Accept-Ranges", "bytes");
            response.setContentLength(buffer.length);
            response.getOutputStream().write(buffer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


	/**
	 * 压缩成ZIP 方法1
	 * @param srcDir 压缩文件夹路径
	 * @param out    压缩文件输出流
	 * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
	 * 							false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
	 * @throws RuntimeException 压缩失败会抛出运行时异常
	 */
	public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
		throws RuntimeException{

		long start = System.currentTimeMillis();
		ZipOutputStream zos = null ;
		try {
			zos = new ZipOutputStream(out);
			File sourceFile = new File(srcDir);
			compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
			long end = System.currentTimeMillis();
			System.out.println("压缩完成,耗时:" + (end - start) +" ms");
		} catch (Exception e) {
			throw new RuntimeException("zip error from ZipUtils",e);
		}finally{
			if(zos != null){
				try {
					zos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	/**
	 * 压缩成ZIP 方法2
	 * @param srcFiles 需要压缩的文件列表
	 * @param out 	        压缩文件输出流
	 * @throws RuntimeException 压缩失败会抛出运行时异常
	 */
	public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
		long start = System.currentTimeMillis();
		ZipOutputStream zos = null ;
		try {
			zos = new ZipOutputStream(out);
			for (File srcFile : srcFiles) {
				byte[] buf = new byte[BUFFER_SIZE];
				zos.putNextEntry(new ZipEntry(srcFile.getName()));
				int len;
				FileInputStream in = new FileInputStream(srcFile);
				while ((len = in.read(buf)) != -1){
					zos.write(buf, 0, len);
				}
				zos.closeEntry();
				in.close();
			}
			long end = System.currentTimeMillis();
			System.out.println("压缩完成,耗时:" + (end - start) +" ms");
		} catch (Exception e) {
			throw new RuntimeException("zip error from ZipUtils",e);
		}finally{
			if(zos != null){
				try {
					zos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}


	/**
	 * 递归压缩方法
	 * @param sourceFile 源文件
	 * @param zos		 zip输出流
	 * @param name		 压缩后的名称
	 * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
	 * 							false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
	 * @throws Exception
	 */
	private static void compress(File sourceFile, ZipOutputStream zos, String name,
								 boolean KeepDirStructure) throws Exception{
		byte[] buf = new byte[BUFFER_SIZE];
		if(sourceFile.isFile()){
			// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
			zos.putNextEntry(new ZipEntry(name));
			// copy文件到zip输出流中
			int len;
			FileInputStream in = new FileInputStream(sourceFile);
			while ((len = in.read(buf)) != -1){
				zos.write(buf, 0, len);
			}
			// Complete the entry
			zos.closeEntry();
			in.close();
		} else {
			File[] listFiles = sourceFile.listFiles();
			if(listFiles == null || listFiles.length == 0){
				// 需要保留原来的文件结构时,需要对空文件夹进行处理
				if(KeepDirStructure){
					// 空文件夹的处理
					zos.putNextEntry(new ZipEntry(name + "/"));
					// 没有文件,不需要文件的copy
					zos.closeEntry();
				}

			}else {
				for (File file : listFiles) {
					// 判断是否需要保留原来的文件结构
					if (KeepDirStructure) {
						// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
						// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
						compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
					} else {
						compress(file, zos, file.getName(),KeepDirStructure);
					}

				}
			}
		}
	}

	/**
	 * 创建文件顺便创建父目录
	 *
	 * @param path 文件字符串路径例如d:/fulld/why/ass/a/asd
	 */
	public static void createFile(String path) {
		createFile(new File(path));
	}

	/**
	 * 创建文件顺便创建父目录
	 *
	 * @param file file类
	 */
	private static void createFile(File file) {
		if (file.exists() && file.isFile()) {
			file.delete();
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		File parentFile = file.getParentFile();
		if (parentFile.exists()) {
			if (parentFile.isFile()) {
				parentFile.delete();
				parentFile.mkdirs();
			}
		} else {
			parentFile.mkdirs();
		}
		try {
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建文件夹顺便创建父目录
	 *
	 * @param path 文件夹的路径字符串例如d:/fulld/why/ass/a/asd/
	 * @return 如果本来就存在或者创建成功,那么就返回true
	 */
	public static void mkdirs(String path) {
		mkdirs(new File(path));
	}

	/**
	 * 创建文件夹顺便创建父目录
	 *
	 * @param file file类
	 */
	public static void mkdirs(File file) {
		if (file.exists() && file.isDirectory()) {
			return;
		}
		if (file.exists()) {
			file.delete();
			file.mkdirs();
		} else {
			file.mkdirs();
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
三、HttpClient使用

使用httpclient,需要下载httpclient-4.5.jar、httpmime-4.5.jar两个包,下载地址为:http://hc.apache.org/downloads.cgi 大致看了下源码,其实也是使用字符拼接,只是封装后使用起来更简洁方便一些。、
httpclient需要注意的4点:
1.HttpClient4.3版本往后,原来的MultipartEntity过时不建议再使用了,替换成新的httpmime下面的MultipartEntityBuilder
2.multipartEntity 最好设置contentType和boundary,不然会导致后面接收文件时的第一种方法接收不到文件报错。
3.使用addBinaryBody的坑:addBinaryBody 有6种不同用法,一般都是如下代码所示上传File即可,但是当传byte[]字节数组时,必须使用4参传值,且第四参必须带后缀名,例如:entityBuilder.addBinaryBody(“file”,new byte[]{},ContentType.DEFAULT_BINARY,“fileName.jpg”);否则会导致接收文件时getFileNames()为空。
4.不使用addBinaryBody,也可以直接使用addPart,先把文件转换成FileBody就可以了
contentType使用【multipart/form-data】:它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件,
boundary:请求体中的boundary参数指定的就是分隔体,请求参数之间需要通过分隔体分隔,不然就会被识别成一个参数。

四、参考链接

multipart/form-data

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/895597
推荐阅读
相关标签
  

闽ICP备14008679号