springboot项目:用户在前端发送一张图片给服务器作为头像。后端接收到图片以后,把图片存到本地磁盘。然后把图片的地址存到数据库,前端显示用户头像时用<img src="存到数据库里的图片地址">
前端代码:修改名字为accountName的头像。新头像是file文件。
<form method="post" action="/updateAccountPic" enctype="multipart/form-data">
<input type="text" name="accountName" v-model="account.accountName" style="display: none">
<span>修改头像:</span><input type="file" name="file"><br>
<span></span><input type="submit" value="提交">
</form>
后端 /updateAccountPic 接口代码:后端收到accountName和file (HttpServletResponse response 这个参数是我这个项目做页面跳转用的,可以忽略)。首先通过一个UploadFile类的静态方法uploadFile()处理file参数,UploadFile.uploadFile()返回一个地址给accountPic。UploadFile.uploadFile()第一个参数是file,第二个参数是你要存图片的磁盘的目录,意思是把file文件存到“D:/springbootZHSH”这个目录下,然后把地址返回一个地址给accountPic。最后一句话就是把地址插入数据库了
@PostMapping("/updateAccountPic")
public void updateAccountPic(String accountName, @RequestParam(value = "file") MultipartFile file,HttpServletResponse response) {
String accountPic = UploadFile.uploadFile(file,"D:/springbootZHSH");
if (accountPic == null){
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
writer.write("<script>alert('图片上传失败');</script>");
writer.write("<script>window.location.href='personData.html'</script>");
}
dmlService.updateAccountPic(accountPic,accountName,response);
}
UploadFile.uploadFile():
public class UploadFile {
public static String uploadFile(MultipartFile file,String uploadPath){
//如果文件是空,返回空
if (file.isEmpty()) {
return null;
}
//获取这个文件的名字,目的是获取这个文件的后缀名
String fileName = file.getOriginalFilename();
//获取后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//为上传的文件建立一个新名字,避免文件名重复。这里用当前时间戳 加 一个6位随机数 加 文件后缀名
fileName = System.currentTimeMillis() +""+ ((int)(Math.random()*1000000)) + suffixName;
//在磁盘创建这个文件目录
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
//创建这个绝对路径的文件对象
File uploadFile = new File(uploadDir + uploadDir.separator + fileName);
try {
//把file转移给uploadFile
file.transferTo(uploadFile);
} catch (IOException e) {
e.printStackTrace();
}
//最后,这里没有直接返回绝对地址,而是返回了以“picture”开头的文件。
return "picture/"+fileName;
}
}
这里不直接返回绝对路径的地址的原因是,例如标签<img src="D:/springZHSH/pic.jpg">,在前端页面图片也显示不出来。这个img标签会发送一个请求"http://localhost:8080/D:/springZHSH/pic.jpg"给后端,后端识别不了这个请求,图片显示不出来。
解决办法,添加拦截器:
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("picture/**").addResourceLocations("file:D:/springbootZHSH/");
}
}
这个拦截器的意思可以理解为是拦截picture请求路径下的所有请求,转移到D:/springbootZHSH目录里,寻找匹配的项目
标签<img src="picture/pic.jpg">发送“http://localhost:8080/picture/pic.jpg”请求时会被拦截转移到D:/springbootZHSH目录里,寻找这个目录里的pic.jpg文件。
这样,数据库里面的都是picture开头的文件地址,这些地址绑定到前端的img标签,img标签发送请求时都能被拦截器拦截并且转移到磁盘目录里。这样图片就可以正常显示了。