springboot实战代码:【如何优雅地返回图片】
本文将会总结返回图片地常用方法:
- 流方式返回:主要是实现方式不一样,基于response和HttpConvertMessage
- base64返回
@RestController
@RequestMapping("/")
public class ImgController {private String imgPath = "E:\\meme.png";
private InputStream getImgInputStream() throws FileNotFoundException {
return new FileInputStream(new File(imgPath));
}
依赖 【springboot实战代码之如何优雅地返回图片】下面使用的IOUtils大家都应该很熟悉了,来自经典的common-io模块
commons-io
commons-io
2.6
1.基于response返回 非常基础也简单的方式:
import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;
/**
* 使用response输出图片流
*/
@GetMapping("/img-response")
public void getImage(HttpServletResponse resp) throws IOException {
final InputStream in = getImgInputStream();
resp.setContentType(MediaType.IMAGE_PNG_VALUE);
IOUtils.copy(in, resp.getOutputStream());
}
2.基于produces返回字节流 2.1返回裸字节流 我们先来看如果直接返回图片的字节流是什么情况:
/**
* 试试直接返回字节流,不指定content-type
*/
@GetMapping(value = "https://www.it610.com/img-byte")
public byte[] getImageByte() throws IOException {
final InputStream in = getImgInputStream();
return IOUtils.toByteArray(in);
}
结果如下:乱码了,因为content-type不对
文章图片
2.2指定content-type返回字节流 使用produces指定类型:这里我们指定2种类型,看看会发生什么
@GetMapping(value = "https://www.it610.com/img-media-type",
produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
public byte[] getImage() throws IOException {
final InputStream in = getImgInputStream();
return IOUtils.toByteArray(in);
}
图片可以正常返回,但是仔细一看,response header里的
content-type
是image/jpeg
文章图片
原因在于当我们默认请求时,springboot匹配地第一种类型jpeg,虽然我们是png图片。
那我们如何让其返回地content-type为
image/png
呢?通过读取源码注释我们知道:
文章图片
只需要在请求时传我们想要地
Accept
就可以了,下面是postman地示例:文章图片
事实上,这个方法还可以对我们上面的
/img-byte
接口使用,就不会返回乱码了文章图片
同时,如果我们传了不支持的类型,会得到
406
错误:文章图片
2.3直接下载图片文件 如果我们想直接弹出下载框,那么可以指定content-type为:
application/octet-stream
@GetMapping(value = "https://www.it610.com/img-file.png",
produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
public byte[] getImageFile() throws IOException {
final InputStream in = getImgInputStream();
return IOUtils.toByteArray(in);
}
文章图片
@GetMapping(value = "https://www.it610.com/img/{iconId}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE})
public byte[] getImage(@PathVariable String iconId) throws IOException {
final GisIcon icon = iconService.getById(iconId);
if (icon == null) {
throw new IllegalArgumentException("不存在此图片");
}
final FileInputStream fio = new FileInputStream(new File(iconService.getSavePath(icon.getUsername(),
icon.getName(), icon.getId())));
byte[] bytes = new byte[fio.available()];
log.info("读取文件结果:{}", fio.read(bytes, 0, fio.available()));
return bytes;
}
3.base64图片
import java.util.Base64;
@GetMapping("/img-base64")
public String getBase64Img() throws IOException {
final byte[] bytes = IOUtils.toByteArray(getImgInputStream());
return Base64.getEncoder().encodeToString(bytes);
}
前端接收:
function reqListener (base64) {
var body = document.getElementsByTagName("body");
var img = document.createElement("img");
img.src = "data:image/png;
base64, "+base64;
body.appendChild(img);
}var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://localhost:8013/img-base64");
oReq.send();
推荐阅读
- 第五节:SpringBoot常用注解介绍
- 第四节:SpringBoot中web模版数据渲染展示
- SpringBoot2022【草稿】
- 聊聊springboot项目全局异常处理那些事儿
- 第一节:创建SpringBoot项目并运行HelloWorld
- springboot管理系统[基于员工角色和文件权限的分级的后台管理系统源码]
- SpringBoot之@ComponentScan和@SpringBootApplication扫描覆盖问题
- mybatis|记mybatis查询null字段导致的NPE
- SpringBoot|SpringBoot 整合 druid数据源
- springboot项目配置application添加图片映射 (windows and linux 都可使用)