方法一:直接使用本地文件
这种方法的原理是把本地文件夹映射为服务器地址,
我们可以使用配置类来实现:
package com.dzy.config;
import com.dzy.utils.RootFolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebAppConfigurer extends WebMvcConfigurationSupport {
@Autowired
private RootFolderUtils rootFolderUtils; // 非必须
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
String path = rootFolderUtils.getPicFolder();
// 这一句不加,你的项目内的静态资源就没了
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/pic/**").addResourceLocations(path);
}
}
有几个需要注意的点:
-
我们继承的类是
WebMvcConfigurationSupport
,而不是WebMvcConfigurationAdapter
,而后者已经被弃用了。 -
当我们写了第19行代码时,SpringBoot默认配置的静态资源就被冲掉了,所有要把第18行的代码写上,因为我的项目只有static中有静态资源,就只写了static。
-
第19行的path是本地文件地址,必须以
file:
开头,这里我稍微魔改了一下,path其实是file:E://csdn/
.
然后在前端页面的显示:
<img th:src="@{/pic/1.png}"/>
这里使用了thymeleaf模板引擎,所以是th:src。
方法二:使用字节流
这种方法的原理是让把图片放到网络上,然后让img标签访问
首先些controller类:
package com.dzy.controller;
import com.dzy.utils.RootFolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
@Controller
@RequestMapping("/picture")
public class PictureController {
@Autowired
private RootFolderUtils rootFolderUtils;
@RequestMapping(value = "{image_name}", produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<byte[]> getImage(@PathVariable("image_name") String image_name) throws Exception{
System.out.println(image_name);
byte[] imageContent ;
String path = "E:/csdn/" + image_name + ".png";
imageContent = fileToByte(new File(path));
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<>(imageContent, headers, HttpStatus.OK);
}
public static byte[] fileToByte(File img) throws Exception {
byte[] bytes = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
BufferedImage bi;
bi = ImageIO.read(img);
ImageIO.write(bi, "png", baos);
bytes = baos.toByteArray();
} catch (Exception e) {
System.out.println(img.getAbsolutePath());
e.printStackTrace();
} finally {
baos.close();
}
return bytes;
}
}
然后是前端页面:
<img th:src="@{/picture/1}"/>
但是这里出现了问题,即使我写@{/picture/1.png}",也只能识别到1,小数点后面的东西都消失了,所以我在controller的第29行后面补上了.png
。
但是这也带来了一个新的问题,就是传不进后缀名会导致无法判断图片格式,不能选择正确的controller。这个问题可以通过把@{/picture/1}
换成@{/png/1}
,@{/jpg/1}
;或者去掉小数点@{/picture/1png}然后在程序里把小数点补上等方法解决。
方法三:使用字节流+ajax
首先解决方法二的遗留问题,把图片名称转换为URL,所以我们编写一个工具类:
@Component
@ComponentScan(basePackages = "com.dzy.utils")
public class PictureUtils {
@Autowired
private ProgramUtils programUtils;
public String image2Url(String str){
String res = programUtils.getBaseUrl();
String[] strs = str.split("\\.");
if (strs.length != 2){
throw new IllegalArgumentException("not a picture, it should be xxx.xxx");
}
return res + strs[1].toLowerCase() + "/" + strs[0];
}
}
然后在前端页面使用Ajax,这里用的是layui中的Ajax。
页面部分:
<img id="big-pic" src="" alt=""/>
Ajax部分:
//ajax请求区域
layui.use('layer', function () {
var layer = layui.layer;
var index = null;
var $ = layui.jquery;
$.ajax({
url:'/homeC/pic',
method:'post',
data:{},
dataType:'JSON',
async:true,
success:function(res){
console.log(res);
$("#big-pic").attr("src", res.url);
$("#describe").html(res.describe);
},
error:function (data) {
console.log(data)
}
});
});
请求的URL是:
@PostMapping(value = "/homeC/pic")
public Home bigPic(){
return homeDao.getValues(); // 返回对象的url属性就是图片字节流的地址,如xxx:8080/png/name
}