SpringMVC使用ResponseEntity实现文件下载,及图片base64的字节数组上传于下载

本文主要通过ResponseEntity<byte[]>实现文件下
该类实现响应头、文件数据(以字节存储)、状态封装在一起交给浏览器处理以实现浏览器的文件下载。
ResponseEntity参数解释:ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus statusCode)
其中ResponseEntity<T> extends HttpEntity<T>,很明显的继承关系,HttpEntity是一个实体类,在new ResponseEntity<byte[]>(b, headers, statusCode);这句初始化的时候,会将T body, MultiValueMap<String, String> headers两个参数传给父类,本类中存放状态码,在HttpEntity类的源码中可以看到:

public HttpEntity(T body, MultiValueMap<String, String> headers) {
this.body = body;
HttpHeaders tempHeaders = new HttpHeaders();
if (headers != null) {
tempHeaders.putAll(headers);
}
//将header头转变成只能读取的对象,而不是写入的对象。
this.headers = HttpHeaders.readOnlyHttpHeaders(tempHeaders);
}

HttpHeaders类说明:表示HTTP请求和响应头,将字符串头名映射到字符串值的列表。
在这里为什么要用HttpHeaders类,是因为MultiValueMap接口的实现类是:HttpHeaders、LinkedMultiValueMap以及静态类MultiValueMapAdapter
话不多说直接上代码:

//下载练习

@GetMapping("/download")
public ResponseEntity<byte[]> download(@RequestParam(name = "id") Long id, HttpServletRequest request) {
TemplateDto byId = getBaseService().findById(id);
HttpHeaders headers = new HttpHeaders();
String fileName = null;
try {
fileName = FileExtraUtils.handleFileName(request, "download.pdf");
} catch (UnsupportedEncodingException e) {
//ignore
log.warn("文件名处理出错", e);
}
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //二进制流(或者字节数组)的形式返回

return new ResponseEntity<>(byId.getTemplaeContent(), headers, HttpStatus.OK);
}

或者根据临时文件保存的路径获取输入流,然后copy给输出流进行下载
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(filePath);
outputStream = response.getOutputStream();
response.setContentType("application/x-download");
response.addHeader("Content-Disposition", "attachment;filename=" + info.getFileName());
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}



//上传文件并保存
@PostMapping("/upload")
public void upload(@Param("file") MultipartFile file, HttpServletResponse response) throws IOException {
File tempFile;
try {
tempFile = File.createTempFile(file.getOriginalFilename(), ".pdf");
file.transferTo(tempFile);
HashMap data = new HashMap();
data.put("fileName", tempFile.getCanonicalPath());
data.put("displayName", file.getOriginalFilename());
ResultDto dto = ResultDtoFactory.toAckData(data);
response.setContentType("text/html; charset=utf-8");
response.getWriter().write(JSON.toJSONString(dto));
} catch (IOException e) {
log.error("保存文件失败", e);
ResultDto dto = ResultDtoFactory.toNack("文件上传失败");
response.setContentType("text/html; charset=utf-8");
response.getWriter().write(JSON.toJSONString(dto));
}
}

@Override
public ResultDto create(TemplateDto templateDto) {
String fileName = templateDto.getFileName();
try (FileInputStream fis = new FileInputStream(new File(fileName))) {
templateDto.setTemplaeContent(IOUtils.toByteArray(fis));
} catch (IOException e) {
log.error("读取模版内容出错", e);
return ResultDtoFactory.toNack("读取模板内容出错,请重新上传");
}
getBaseService().save(templateDto);
return ResultDtoFactory.toAck();
}

//另外图片的上传于下载
@PostMapping("/upload")
public void upload(@RequestParam String configKey, MultipartFile file, HttpServletResponse response) throws IOException {
ConfigDto configDto = new ConfigDto();
configDto.setConfigKey(configKey);
String base64Content = Base64Utils.encodeToString(IOUtils.toByteArray(file.getInputStream()));
configDto.setConfigValue(base64Content);
configService.save(configDto);
ResultDto resultDto = ResultDtoFactory.toAck();
response.setContentType("text/html; charset=utf-8");
response.getWriter().write(JSON.toJSONString(resultDto));
}

@GetMapping("/download")
public void download(@RequestParam(required = true) String configKey, HttpServletResponse response) throws IOException {
List<ConfigDto> byKey = configService.findByKey(configKey);
if (CollectionUtils.isNotEmpty(byKey)) {
ConfigDto configDto = byKey.get(0);
if(configDto!=null){
String base64Content = configDto.getConfigValue();
byte[] bytes = Base64Utils.decodeFromString(base64Content);
IOUtils.copy(new ByteArrayInputStream(bytes), response.getOutputStream());
response.getOutputStream().flush();
}
}
}