公司来了个需求,要求中间层调用图片接口获取图片流,然后直接将图片以文件流的形式调用其他的服务将图片发送出去。
查询了一些资料进行了整理。
1.调用底层图片接口,获取文件流。
public InputStream requestFile() throws IOException {
HashMap<String, Object> param = new HashMap<>();
param.put("params", "{mapId:1}");
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Resource> entity = restTemplate.getForEntity(FILE_URL, Resource.class, param);
InputStream inputStream = Objects.requireNonNull(entity.getBody()).getInputStream();
return inputStream;
}
2.调用上层图片接口,将图片以流的形式发送上去。
public void pushFile() throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("mapId","1");
param.add("devSn","12312312");
InputStream inputStream = fileRequest.requestFile();
InputStreamResource fileResource = new InputStreamResource(inputStream) {
@Override
public long contentLength() {
return 2633;
}
@Override
public String getFilename() {
return "hello.jpg";
}
};
param.add("inputStream", fileResource);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(param, headers);
new RestTemplate().exchange(UPLOAD_URL, HttpMethod.POST, requestEntity, String.class);
inputStream.close();
}
注:
【1】需要将发送文件流(InputStream)进行封装,用InputStreamResource进行封装,并需要重写父类方法contentLength、getFilename,告知文件的大小以及文件名。
【2】发送文件需要设置content-type为multipart/form-data。
3.Controller层接收文件
在application.yml中可以配置接收文件的大小限制。
@PostMapping(value = "/map/upload")
public String upload(List<MultipartFile> inputStream, String mapId, String devSn) {
BufferedOutputStream stream = null;
for (MultipartFile file : inputStream) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(file.getOriginalFilename()));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
return "fail";
}
} else {
return "fail";
}
}
return "success";
}
注:参数类型为List<MultipartFile>可以直接映射, file.getBytes()即可获取到文件的字节码信息,处理方式因需求而议即可。