【Springboot】springboot中上传图片的访问不了,配置虚拟化路径解决(后端)
在springboot中,上传图片或文件上传成功后,却无法访问。
在springboot中,用相对的路径储存,也只是存储在临时的目录,一重启文件就会没有了。并且打为jar后,存入文件也会有问题。
这时,需要配置一个虚拟路径,映射到物理路径上。比如在服务器将文件存在/usr/upload文件夹下,同时映射的路径为http://localhost:8080/image。那么处理上传文件的后台程序则写入文件/usr/upload文件夹下,通过浏览器访问localhost:8080/image/xxx.png,就相当于访问/usr/upload文件夹的xxx.png。
具体的实现步骤-》
前端使用的参考博客园,使用的是TinyMCE编辑器。粘贴图片,就可以上传。
这个异步不是使用form,所以不讨论上传的工具类。
在后端中,处理上传的handler:
package com.hj.blog.handler; import com.hj.blog.service.UploadService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.io.*; @RestController public class UploadHandler { private Logger logger = LoggerFactory.getLogger(UploadHandler.class); @Autowired private UploadService uploadService; @RequestMapping("/uploadimg") public String uploadimg(HttpServletRequest request) throws IOException, ServletException { // handler调用文件上传的service 得到文件的虚拟路径 String filepath = uploadService.uploadImg(request); return filepath; } }
处理文件上传的service,在service中将上传的文件夹和映射的文件夹都放在配置文件中:
package com.hj.blog.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; @Service public class UploadService { private Logger logger = LoggerFactory.getLogger(UploadService.class); // 文件的真实路径 @Value("${file.uploadFolder}") private String realBasePath; @Value("${file.accessPath}") private String accessPath; public String uploadImg(HttpServletRequest request) throws IOException, ServletException { InputStream inputStream = request.getInputStream(); //获取请求头中Contect-Type的值 // 图片后缀 String imgSuffix = "png"; Enumeration enumeration=request.getHeaderNames(); while(enumeration.hasMoreElements()) { String name=(String)enumeration.nextElement(); if(name.equals("content-type")){ String value=request.getHeader(name); imgSuffix = value.split("/")[1]; logger.info("header中" + name + " " + value); logger.info("文件后缀:" + imgSuffix); } } // 文件唯一的名字 String fileName = UUID.randomUUID().toString() + "." +imgSuffix; Date todayDate = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String today = dateFormat.format(todayDate); // 域名访问的相对路径(通过浏览器访问的链接-虚拟路径) String saveToPath = accessPath + today + "/"; // 真实路径,实际储存的路径 String realPath = realBasePath + today + "/"; // 储存文件的物理路径,使用本地路径储存 String filepath = realPath + fileName; logger.info("上传图片名为:" + fileName+"--虚拟文件路径为:" + saveToPath +"--物理文件路径为:" + realPath); // 判断有没有对应的文件夹 File destFile = new File(filepath); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } // 输出流 输出到文件 OutputStream outputStream = new FileOutputStream(destFile); // 缓冲区 byte[] bs = new byte[1024]; int len = -1; while ((len = inputStream.read(bs)) != -1) { outputStream.write(bs,0,len); } inputStream.close(); outputStream.close(); // 返回虚拟路径,给链接访问 return saveToPath+fileName; } }
application.properties:
# 上传的服务器上的映射文件夹
file.accessPath=/uploadimg/
#静态资源对外暴露的访问路径
file.staticAccessPath=/uploadimg/**
#文件上传目录(注意Linux和Windows上的目录结构不同)
#file.uploadFolder=/root/uploadFiles/
file.uploadFolder=C://File_rec/tmp/
关键的配置类:
package com.hj.blog.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 设置虚拟路径,访问绝对路径下资源 */ @Configuration public class UploadConfig implements WebMvcConfigurer{ @Value("${file.staticAccessPath}") private String staticAccessPath; @Value("${file.uploadFolder}") private String uploadFolder; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(staticAccessPath).addResourceLocations("file:" + uploadFolder); } }
通过最后的配置类,设置了虚拟的路径到物理的路径中。也可以正常的访问图片了。