需求:
- 实现一个api可以上传文件及各种参数
过程:
- 因为是上传文件所以不可能是get 请求 所以添加一个controller 行为
@PostMapping(path = "/post")
- 存在特有的必填参数所有在controller 里加上对应参数
@RequestParam(name = "test1") String test1 @RequestParam(name = "test2") String test2
- 因为上传文件binary 是流的形式所以加上 文件流
InputStream dataStream
- 文件流可以通过
byte[] targetArray = inputStream.readAllBytes();
转化成字节数组的形式被java 获取,之后再对文件做处理
衍生:
- 上传多个文件,存在非必填参数
过程:
- 如果是多个文件单独的流已经无法满足,传递方式也由原先的binary 转换成 form-data
- 既然已经不是流的形式,之前的获取请求参数的方式就不可行,通过httpRequest获取
HttpServletRequest httpRequest
- 可以通过 StandardServletMultipartResolver 来判定是否为多文件
StandardServletMultipartResolver resolver = new StandardServletMultipartResolver(); resolver.isMultipart(httpRequest)
- 如果是单文件就通过 request 来获取文件流
InputStream inputStream = httpRequest.getInputStream() byte[] targetArray = inputStream.readAllBytes();
- 如果是多文件就将HttpServletRequest 转换成 MultipartHttpServletRequest,并获取文件map
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(httpRequest); MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
- 循环map 获取文件信息
multiFileMap.forEach( (String key, List<MultipartFile> multipartFileList) -> { for(MultipartFile obj : multipartFileList) { try { byte[] fileByte = obj.getBytes(); MultiPartParam multiPartParam = new MultiPartParam(key, fileByte, obj.getOriginalFilename()); fileList.add(multiPartParam); } catch (Exception e) { e.printStackTrace(); } } });
- 获取非必填参数可以通过httpRequest 获取
Map<String, String[]> params = httpRequest.getParameterMap()
注意:
- InputStream dataStream 和 @RequestBody 不能同时使用,同时使用 dataStream 会失效
@PostMapping(path = "/post")
public ResponseEntity postFile(
HttpServletRequest httpRequest,
@RequestParam(name = "productId") String productId,
@RequestParam(name = "code") String code,
@RequestParam(name = "n", defaultValue = "3", required = false) String topn
) {
try (InputStream inputStream = httpRequest.getInputStream()){
ReactHttpClient httpClient = ReactHttpClient.create(0, 5 * 60000);
StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
HttpResponse response;
String engineUrl = "http://10.40.10.92:5003?n=" + topn;
Map<String, String> params = new HashMap<>();
Map<String, String> header = new HashMap<>();
if (resolver.isMultipart(httpRequest)) {
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(httpRequest);
MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
List<MultiPartParam> fileList = new ArrayList<>();
multiFileMap.forEach((String key, List<MultipartFile> multipartFileList) -> {
for(MultipartFile obj : multipartFileList) {
try {
byte[] fileByte = obj.getBytes();
MultiPartParam multiPartParam = new MultiPartParam(key, fileByte, obj.getOriginalFilename());
fileList.add(multiPartParam);
} catch (Exception e) {
e.printStackTrace();
}
}
});
response = httpClient.postBody(engineUrl, params, fileList, header).block();
} else {
byte[] targetArray = inputStream.readAllBytes();
response = httpClient.postBody(engineUrl, targetArray).block();
}
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(response.getResponse());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}