【问题标题】:Why can I run my app VSCode but not correctly in CLI?, its a spring boot application为什么我可以在 CLI 中运行我的应用程序 VSCode 但不能正确运行?,它是一个 Spring Boot 应用程序
【发布时间】:2020-09-01 14:52:25
【问题描述】:

我正在 Spring Boot 中构建一个 Web 应用程序。

开发环境是Gradle,我用的是visual studio code。

我正在使用visual studio code的调试功能,spring boot仪表板,当我启动应用程序时,页面显示正确,但是当我将web应用程序制作为jar文件并使用java -jar运行时,它没有'不适用于某些页面转换。

请告诉我我应该怎么做才能使它工作以及发生了什么。 (我认为spring boot找不到some path,但我不知道是什么以及如何修复它。)

这是我访问「localhost:8080/gallery」时所在的页面

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Sep 01 23:09:16 JST 2020
There was an unexpected error (type=Internal Server Error, status=500).

以下是我使用 java -jar 访问特定图库页面时遇到的错误。

2020-09-01 23:09:14.129  INFO 15464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-09-01 23:09:14.143  INFO 15464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 14 ms
Check image file path
2020-09-01 23:09:16.656 ERROR 15464 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
        at com.example.sweepea.GetImage.getImage(GetImage.java:23) ~[classes!/:na]
        at com.example.sweepea.swepeaController.getGallery(swepeaController.java:21) ~[classes!/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]

控制器类中的方法如下。 「index」和「about」是工作。

    @GetMapping("/index")
    public String getIndex(){
        return "index";
    }

    @GetMapping("/gallery")
    public String getGallery(Model model){
            List<String> imagePath = new GetImage().getImage(new File("src/main/resources/static/images"));
            model.addAttribute("imagePath", imagePath);
            return "gallery";
        }

    @GetMapping("/about")
    public String getAbout(){
            return "about";
        }
}

GetImage 类如下。 就是获取.jpg图片,添加List并返回。

@Service
public class GetImage {
    String month = "202009";
    List<String> pathname = new ArrayList<String>();
    
    List<String> getImage(File file){
        File[] filelist = file.listFiles();
        
        

        if(filelist == null){
            System.out.println("Check image file path");
        }

        for (File tmpFile : filelist){
            if(tmpFile.isDirectory()){
                month = tmpFile.getName();
                //System.out.println(month);
                //pathname.add(month);
                getImage(tmpFile);
            
            }else{
                String imagePath = "images/" + month + "/" + tmpFile.getName();
                if(imagePath.substring(imagePath.length() - 3).equals("jpg")){
                    pathname.add(imagePath);
                    //System.out.println(imagePath);
                }
            }

        }
        return pathname;
    }
}

图库.html

 <body>
        <div id="content">
            <header class="page_header wrapper" >
                <h1><a th:href="@{'/index'}"><img class="logo" th:src="@{images/logo.svg}" alt=""></a></h1>
                <nav class="main_nav">
                    <ul>
                        <ii><a th:href="@{'/index'}">TOP</a></ii>
                        <ii><a th:href="@{'/gallery'}">GALLERY</a></ii>
                        <ii><a th:href="@{'/about'}">ABOUT</a></ii>
                    </ul>
                </nav>
            </header>
            <main>
                <div class="edition">
                    <p>sub title</p>
                </div>
            
            
            
            <h2 class="mounth">Gallery</h2>
            <div class="grid item">
                    <a th:each="image : ${imagePath}" th:href="@{${image}}"><img th:src="@{${image}}" alt=""></a>

            </div>

            
            
            
            </main>
        </body>

源码树就是这样


└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── sweepea
    │   │               ├── DemoApplication.java
    │   │               ├── GetImage.java
    │   │               ├── Test.java
    │   │               └── swepeaController.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       │   ├── logo.svg
    │       │   ├── images
    │       │   │   ├── 201910
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 201911
    │       │   │   ├── 201912
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202001
    │       │   │   ├── 202002
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202003
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202004
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202005
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202006
    │       │   │   ├── 202007
    │       │   │   ├── 202008
    │       │   │   │   ├── 1.jpg
    │       │   │   ├── 202009
    │       │   │   ├── logo.svg
    │       │   │   └── logo_favicon.png
    │       │   └── style.css
    │       └── templates
    │           ├── about.html
    │           ├── gallery.html
    │           ├── index.html
    │           └── video.html
    └── test
        └── java
            └── com
                └── example
                    └── sweepea
                        └── DemoApplicationTests.java

【问题讨论】:

    标签: java spring-boot gradle visual-studio-code


    【解决方案1】:

    这一行:

    List<String> imagePath = new GetImage().getImage(new File("src/main/resources/static/images"));
    

    是问题所在。应始终从 Jar 文件中读取资源,而不是通过指定路径,绝对路径或相对于您运行应用程序的任何目录。

    This article 展示了如何正确地从资源文件夹中读取文件。

    【讨论】:

    • 感谢您的回答。我看到如果我将资源文件夹打包到 jar 中,则无法通过路径规范访问资源文件夹。我还阅读了您给我的链接中的文章。我看到我可以使用“getClass().getClassLoader()”来访问 jar 文件中的文件。我还不明白怎么做,所以我打算这个周末试试。
    【解决方案2】:

    如果您将应用程序打包在一个 jar 中,它不再依赖于源代码。

    如果您在另一个文件夹或另一个服务器上使用java -jar ... 启动您的应用程序,那么new File("src/main/resources/static/images") 将不再工作。

    我认为当您在项目的根文件夹中执行 java -jar ... 时它会起作用,但这可能不是一个长期的解决方案。

    Maven 将 src/main/resources 文件夹视为需要包含在 jar 中的文件的输入文件夹,因此打包后,这些文件将以 getClass().getResource("/static/images/202008/1.jpg") 的形式从 java 中可用,这就是它们在 Spring 中的服务方式引导(使用 ResourceHttpRequestHandler,不带static/ 前缀)。

    如果您想稍后添加图像而无需重新构建和重新打包您的应用程序,最好使用绝对服务器路径,例如 "C:\gallery\images""/opt/gallery/images"

    【讨论】:

    • 感谢您的回答。正如您告诉我的那样,我在服务器上创建了一个目录并将图像放在服务器上并加载!我还确认我能够通过在项目的根目录中使用 java -jar 执行它来加载它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    相关资源
    最近更新 更多