Heroku SpringBoot ClassPathResource 获取 FileNotFoundException

2023-12-31

我在 Heroku 上部署了一个 SpringBoot 项目,尽管它在本地运行得很好,但我得到了 FileNotFoundException 。

这是代码:

@GetMapping(path = "/api/items/image/get/{file_name}")
public ResponseEntity<InputStreamResource> getItemImage(@PathVariable("file_name") String fileName) {
    // append "_thumbsnail" to file name
    fileName = fileName.split("\\.")[0] + "_thumbsnail." + fileName.split("\\.")[1];
    ClassPathResource imgFile = new ClassPathResource("item_image/" + fileName, getClass().getClassLoader());
    try {
        return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG)
                .body(new InputStreamResource(imgFile.getInputStream()));
    } catch (IOException e) {
        e.printStackTrace();
        return ResponseEntity.badRequest().body(null);
    }
}

这是错误:

2019-01-21T14:29:15.221959+00:00 app[web.1]: java.io.FileNotFoundException: class path resource [item_image/1234567890128_thumbsnail.png] cannot be opened because it does not exist
2019-01-21T14:29:15.226272+00:00 app[web.1]: at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
2019-01-21T14:29:15.226412+00:00 app[web.1]: at com.smartscan.api.controller.ItemAPIController.getItemImage(ItemAPIController.java:116)
2019-01-21T14:29:15.226419+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2019-01-21T14:29:15.226447+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2019-01-21T14:29:15.226474+00:00 app[web.1]: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2019-01-21T14:29:15.226502+00:00 app[web.1]: at java.lang.reflect.Method.invoke(Method.java:498)
2019-01-21T14:29:15.226531+00:00 app[web.1]: at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
2019-01-21T14:29:15.226557+00:00 app[web.1]: at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
2019-01-21T14:29:15.226594+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
2019-01-21T14:29:15.226621+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
2019-01-21T14:29:15.226648+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
2019-01-21T14:29:15.226674+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
2019-01-21T14:29:15.226699+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
2019-01-21T14:29:15.226755+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
2019-01-21T14:29:15.226816+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
2019-01-21T14:29:15.226822+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
2019-01-21T14:29:15.226853+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
2019-01-21T14:29:15.226882+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
2019-01-21T14:29:15.226884+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
2019-01-21T14:29:15.226891+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
2019-01-21T14:29:15.226919+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-01-21T14:29:15.226941+00:00 app[web.1]: at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
2019-01-21T14:29:15.226970+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2019-01-21T14:29:15.226999+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-01-21T14:29:15.227006+00:00 app[web.1]: at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
2019-01-21T14:29:15.227045+00:00 app[web.1]: at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
2019-01-21T14:29:15.227058+00:00 app[web.1]: at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
2019-01-21T14:29:15.227059+00:00 app[web.1]: at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
2019-01-21T14:29:15.227084+00:00 app[web.1]: at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)

我之前搜索过是否有人遇到过这个问题,但找不到解决的解决方案。

这是heroku 上的目录结构:

~/target $ ls
classes         mvn-dependency-list.log
generated-sources   smart-scan-0.0.1-SNAPSHOT.jar
generated-test-sources  smart-scan-0.0.1-SNAPSHOT.jar.original
maven-archiver      test-classes
maven-status

这是我创建文件时的日志:

===== itemImageFolder: file:/app/target/smart-scan-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/item_image/1133113.png
2019-01-22T14:47:00.507783+00:00 app[web.1]: ====== Thumps nail created file:/app/target/smart-scan-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/item_image/1133113_thumbsnail.png

这是我加载文件时的日志:

2019-01-22T14:48:04.287928+00:00 app[web.1]: ====== READING RESOURCE file:/app/target/smart-scan-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/item_image/1133113_thumbsnail.png
2019-01-22T14:48:04.291731+00:00 app[web.1]: java.lang.IllegalArgumentException: InputStream must not be null

我如何保存文件:

    URL itemImageFolder = getClass().getClassLoader().getResource("item_image/");
    System.out.println("===== itemImageFolder: " + itemImageFolder.getPath() + imagePath);
    Path rootLocation = Paths.get(itemImageFolder.getPath());
    if (Files.notExists(rootLocation)) {
        Files.createDirectories(rootLocation);
    }
    Files.copy(file.getInputStream(), Paths.get(itemImageFolder.getPath() + imagePath),
            StandardCopyOption.REPLACE_EXISTING);
    // create thumbs nail
    BufferedImage originalImage = ImageIO.read(new File(itemImageFolder.getPath() + imagePath));
    int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
    BufferedImage resizeImageJpg = resizeImage(originalImage, type);
    System.out.println(
            "====== Thumps nail created " + itemImageFolder.getPath() + barcode + "_thumbsnail." + extension);

    ImageIO.write(resizeImageJpg, extension,
            new File(itemImageFolder.getPath() + barcode + "_thumbsnail." + extension));

以及我如何加载文件:

fileName = fileName.split("\\.")[0] + "_thumbsnail." + fileName.split("\\.")[1];
System.out.println("====== READING RESOURCE " + getClass().getClassLoader().getResource("item_image/").getPath() + fileName);
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("item_image/" + fileName);

更新: 我已经通过更改为使用Blob来存储Image来解决这个问题,但是不推荐这种解决方案。所以我仍然需要有在 Heroku 上部署 Spring Boot 应用程序经验的人来帮助我。


虽然我不太清楚为什么在 Heroku 上部署的 Spring 应用程序中无法获取文件路径,但我采用了另一种方法,这可能对其他遇到相同问题的人有所帮助。我利用了 Spring 的 Resource 方法,通过创建一个配置类并将文件内容注入到变量中@Value注解。我已经通过读取文件的 Bean 方法公开了文件内容的 String 值:

@Configuration
public class ResourceFiles {

    @Value("classpath:myfile.ext")
    private Resource myfile;

    @Bean(name = "myfile")
    public String myfile() {
        try (InputStream is = myfile.getInputStream()) {
            return StreamUtils.copyToString(is, Charset.forName("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

然后,我通过使用了文件字符串内容@Autowired注解:

@Autowired
@Qualifier("myfile")
public String myfile;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Heroku SpringBoot ClassPathResource 获取 FileNotFoundException 的相关文章

随机推荐

  • 使用 IntelliJ IDEA 运行 Maven 项目

    我是 IntelliJ IDEA 的新手 我想使用它运行一个简单的 Maven 快速入门项目 我按照所有说明进行操作 该项目已成功构建 但是当我尝试编译并运行它时 Run按钮未激活 看来 IntelliJ IDEA 无法弄清楚主类在哪里 这
  • CGDataProviderCopyData() 实际上复制字节吗?或者只是指针?

    我正在尽可能快地连续运行该方法 并且越快越好 所以显然如果CGDataProviderCopyData 实际上是逐字节复制数据 那么我认为必须有一种更快的方法来直接访问该数据 它只是内存中的字节 任何人都知道如果CGDataProvider
  • 2D 弹性球碰撞物理

    我正在制作一个涉及弹性球物理学的程序 我已经计算出了与墙壁和静止物体碰撞的所有数学公式 但我无法弄清楚当两个移动的球碰撞时会发生什么 我有质量和速度 确切地说是 x 和 y 速度 但每个球的速度及其方向都可以 并且想要这些的公式 请记住 这
  • 为什么自动向下转换不应用于模板函数?

    有人问这个问题 https stackoverflow com questions 45505477关于字符串附加 它是string s s s 2 不编译 人们给出的答案是operator 被定义为模板函数 而operator 不是 所以
  • 更改 Azure AD B2C 注销 URL(将 AzureADB2C/Account/SignedOut 更改为自定义 URL)

    我目前正在构建一个 C Net Core 2 2 应用程序 该应用程序使用 Azure B2C OIDC 进行登录 身份验证 我已经自定义了登录页面 并且知道如何使用自定义页面布局使用我的网站上托管的 CSS 和代码来自定义编辑 忘记密码屏
  • 使用委托作为 LINQ 的 Distinct() 的相等比较器

    我有一个 LINQ Distinct 语句 它使用我自己的自定义比较器 如下所示 class MyComparer
  • 在 Win7 中,某些字体无法像在 Win2K/XP 中那样工作

    我的问题是如何更改字体处理才能在 Windows 7 下正常工作 我确信我已经对以前有效但不再有效的内容做出了假设 但我什至不知道从哪里开始寻找 我祈祷有人可以帮忙 以下是我理解的详细信息 我还在 Microsoft Windows 开发人
  • 应用内购买:用户绑定购买上的“恢复购买”按钮

    我目前正在我的 Swift 应用程序中实现应用内购买 该产品是一种非消耗性产品 可为用户激活一种高级版本 通常 对于非消耗品购买 您必须在应用程序中放置 恢复购买 按钮 强制 然而 我的问题是 该应用程序以及因此的购买是受用户约束的 因此
  • UIPageViewController 子视图控制器之间的水平填充

    我正在使用 UIPageViewController 来显示嵌入在子视图控制器中的图像 NSDictionary options NSDictionary dictionaryWithObject NSNumber numberWithIn
  • Coq - 在 if ... then ... else 中使用 Prop (True | False)

    我对 Coq 有点陌生 我正在尝试实现插入排序的通用版本 我正在实现一个以比较器作为参数的模块 该 Comparator 实现了比较运算符 如 is eq is le is neq 等 在插入排序中 为了插入 我必须比较输入列表中的两个元素
  • 可以从多个模块访问包

    我的项目在 Java 1 8u151 上运行良好 我正在尝试将其升级到 Java 12 但出现以下错误 Package is accessible from more than one module
  • 如何在 emacs 中永久启用 hs-minor-mode

    我在 emacs 文件中使用 thhs 代码来永久启用 hs minor mode 并更改快捷方式 setq default hs minor mode t global set key kbd C c C h kbd C c C h hi
  • 在 Windows Phone 10 中安装 appx 或 appxbundle?

    我正在开发一个 UWP 应用程序 当使用 VS2015 调试它时运行没有任何问题 但当使用 appx 或 appxbundle 安装它时 我已经阅读了很多打包和安装指南 似乎我并没有遗漏任何步骤 我只需要在设备中部署应用程序以仅用于测试目的
  • MySQL 查询值列表

    我想从值列表创建一个查询并返回每个匹配的数据cat 这可行 但不需要options价值 查询值列表的更简单方法是什么 SELECT FROM table1 WHERE option R cat 12 cat 18 cat 30 您可以使用I
  • 设备可锁定第 n 次尝试时的自定义消息

    我正在寻找一种方法来显示设计可锁定模块中各种失败尝试次数的自定义消息 我发现默认情况下只能通知最后一次尝试 https github com plataformatec devise blob master lib devise model
  • 如何使用 C# 获取 .NET 中的当前用户名?

    如何使用 C 获取 NET 中的当前用户名 string userName System Security Principal WindowsIdentity GetCurrent Name
  • 如何在自己的线程上创建表单并在整个应用程序生命周期中保持其打开状态

    我正在创建一个小测试组件 但遇到了问题 基本上 该组件是控制对数据库的所有访问的类上的装饰器 它创建一个带有两个按钮的表单 模拟丢失连接 和 重新连接 按下按钮 不再让函数调用通过包装器 而是开始抛出 NoConnectionExcepti
  • 如何使背景图像即使滚动也保持在左下角

    我想知道是否有一种方法可以使我的背景图像始终保持在左下角 即使用户滚动浏览器也是如此 我当前的CSS可以在网站加载时使图像位于浏览器底部 但是如果我滚动浏览器 它仍然会停留在同一位置 我很感激任何帮助 html body backgroun
  • 如何在 Windows 10 中启用 USB 重定向 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的操作系统是 Windows 7 我有一个远程主机 Windows 8 1 我可以使用 RDP 将本地 USB 设备重定向到 Windo
  • Heroku SpringBoot ClassPathResource 获取 FileNotFoundException

    我在 Heroku 上部署了一个 SpringBoot 项目 尽管它在本地运行得很好 但我得到了 FileNotFoundException 这是代码 GetMapping path api items image get file nam