Spring MVC无法存储图片到应用路径,抛出FileNotFoundException异常
Spring MVC中图片存储到resources/images目录的问题解决
我看你遇到的问题是想把图片存到Spring MVC项目的resources/images目录,但运行代码时抛出了FileNotFoundException,这可是个Spring MVC里存文件的常见坑哦!
问题根源
你原来的代码里用了request.getContextPath()来拼接文件路径:
String file= request.getContextPath()+"/resources/images/imageee.png";
request.getContextPath()返回的是Web应用的上下文访问路径(比如你的/campasAdmin),这是给浏览器访问用的URL路径,不是服务器本地文件系统的真实路径。Java尝试根据这个路径写文件时,找不到对应的本地目录,自然就抛出找不到文件的异常了。
你原来的错误代码
BufferedImage image = null; byte[] imageByte; BASE64Decoder decoder = new BASE64Decoder(); imageByte = decoder.decodeBuffer(studentDetails.getStuImg()); ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); image = ImageIO.read(bis); bis.close(); String file= request.getContextPath()+"/resources/images/imageee.png"; // write the image to a file File outputfile = new File(file); ImageIO.write(image, "png", outputfile);
抛出的异常
java.io.FileNotFoundException: \campasAdmin\resources\images\imageee.png (The system cannot find the path specified) at java.io.RandomAccessFile.open0(Native Method) at java.io.RandomAccessFile.open(Unknown Source) at java.io.RandomAccessFile.<init>(Unknown Source) at javax.imageio.stream.FileImageOutputStream.<init>(Unknown Source) at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(Unknown Source) at javax.imageio.ImageIO.createImageOutputStream(Unknown Source) at javax.imageio.ImageIO.write(Unknown Source) at com.rasvek.cms.controller.StudentController.addfeeCategory(StudentController.java:272) // ... 后续异常栈省略
解决方案:获取真实文件路径
要解决这个问题,关键是拿到resources/images目录在服务器本地文件系统的真实路径,下面给你两种常用的实现方式:
方式一:通过ServletContext获取真实路径
在Controller方法里,从request中获取ServletContext,然后拿到目录的真实路径,还要确保目录存在(不存在就创建):
BufferedImage image = null; byte[] imageByte; BASE64Decoder decoder = new BASE64Decoder(); imageByte = decoder.decodeBuffer(studentDetails.getStuImg()); ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); image = ImageIO.read(bis); bis.close(); // 获取ServletContext,拿到真实路径 ServletContext servletContext = request.getServletContext(); String imageDirPath = servletContext.getRealPath("/resources/images"); // 确保目录存在,不存在则递归创建 File imageDir = new File(imageDirPath); if (!imageDir.exists()) { imageDir.mkdirs(); } // 拼接完整文件路径 String filePath = imageDirPath + File.separator + "imageee.png"; File outputfile = new File(filePath); ImageIO.write(image, "png", outputfile);
方式二:用Spring的ResourceLoader(更推荐)
如果你的Controller是Spring管理的,可以注入ResourceLoader来获取classpath下的目录路径,这种方式更贴合Spring生态:
@Autowired private ResourceLoader resourceLoader; // 你的方法内 public void yourMethod(HttpServletRequest request, ...) throws IOException { BufferedImage image = null; byte[] imageByte; BASE64Decoder decoder = new BASE64Decoder(); imageByte = decoder.decodeBuffer(studentDetails.getStuImg()); ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); image = ImageIO.read(bis); bis.close(); // 获取classpath下images目录的真实路径 Resource resource = resourceLoader.getResource("classpath:images/"); String imageDirPath = resource.getFile().getAbsolutePath(); // 确保目录存在 File imageDir = new File(imageDirPath); if (!imageDir.exists()) { imageDir.mkdirs(); } // 拼接文件路径并写入 String filePath = imageDirPath + File.separator + "imageee.png"; File outputfile = new File(filePath); ImageIO.write(image, "png", outputfile); }
生产环境注意事项
如果你的项目最终是打包成jar包运行的,resources目录是在jar压缩包内部的,此时无法直接写入文件(因为jar包是只读的压缩文件)。所以生产环境更推荐:
- 将图片存储到服务器的外部独立目录(比如Linux的
/opt/cms/images,Windows的D:/cms/images) - 在Spring MVC中配置静态资源映射,让浏览器能访问到这个外部目录的图片:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 映射外部图片目录,浏览器访问/images/xxx.png时会指向外部目录的文件 registry.addResourceHandler("/images/**") .addResourceLocations("file:/opt/cms/images/"); // Windows下改为file:D:/cms/images/ } }
内容的提问来源于stack exchange,提问作者bharath
相关产品推荐
相关产品推荐

