Why can I run my app VSCode but not correctly in CLI?, its a spring boot application

huangapple go评论71阅读模式
英文:

Why can I run my app VSCode but not correctly in CLI?, its a spring boot application

问题

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

开发环境是Gradle,我正在使用Visual Studio Code。

我正在使用Visual Studio Code的调试功能、Spring Boot仪表板,当我启动应用程序时,页面能正确显示,但当我将Web应用程序制作成jar文件并用java -jar运行时,部分页面转换无法正常工作。

请告诉我如何使其正常工作以及出现了什么情况。
(我认为Spring Boot无法找到某些路径,但我不知道是什么路径,以及如何修复它。)

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

Whitewabel 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图像,添加到列表并返回:

@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();
                getImage(tmpFile);
            }else{
                String imagePath = "images/" + month + "/" + tmpFile.getName();
                if(imagePath.substring(imagePath.length() - 3).equals("jpg")){
                    pathname.add(imagePath);
                }
            }
        }
        return pathname;
    }
}

gallery.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>
                    <li><a th:href="@{/index}">TOP</a></li>
                    <li><a th:href="@{/gallery}">GALLERY</a></li>
                    <li><a th:href="@{/about}">ABOUT</a></li>
                </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>
    </div>
</body>

目录结构如下所示:

└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── sweepea
    │   │               ├── DemoApplication.java
    │   │               ├── GetImage.java
    │   │               └── swepeaController.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       │   ├── logo.svg
    │       │   ├── images
    │       │   │   ├── ... (各月份和图像文件)
    │       │   └── style.css
    │       └── templates
    │           ├── about.html
    │           ├── gallery.html
    │           └── index.html
    └── test
        └── java
            └── com
                └── example
                    └── sweepea
                        └── DemoApplicationTests.java
英文:

I'm building a web application in spring boot.

The development environment is Gradle and I am using visual studio code.

I'm using visual studio code's debug function, spring boot dashboard, and when I start the application, the page is displayed correctly, but when I make the web application a jar file and run it with java -jar, it doesn't work with some page transitions.

Please tell me what I should do to make it work and what is happening.
(I think that spring boot can't find the some path, but I don't know what is and how to fix it.)

Here's the page I was on when I accessed 「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).

The following is the error I get when I use java -jar to access a specific gallery page.

2020-09-01 23:09:14.129  INFO 15464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet &#39;dispatcherServlet&#39;
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]

The methods in the controller class are as follows. 「index」and「about」is work.

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

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

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

GetImage class are as follw.
It is get .jpg images , add List and return.

@Service
public class GetImage {
    String month = &quot;202009&quot;;
    List&lt;String&gt; pathname = new ArrayList&lt;String&gt;();
    
    List&lt;String&gt; getImage(File file){
        File[] filelist = file.listFiles();
        
        

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

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

        }
        return pathname;
    }
}

gallery.html

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

            &lt;/div&gt;

            
            
            
            &lt;/main&gt;
        &lt;/body&gt;

source tree is like that


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

答案1

得分: 3

这一行代码:

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

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

这篇文章展示了如何正确地从资源文件夹中读取文件。

英文:

This line:

List&lt;String&gt; imagePath = new GetImage().getImage(new File(&quot;src/main/resources/static/images&quot;));

is the problem. The resources should always be read from within the Jar file, not by specifying path, either an absolute one or relative to whatever directory your run your app from.

This article shows how to properly read file from the resources folder.

答案2

得分: 1

如果你将应用程序打包成一个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 Boot中的提供方式(使用ResourceHttpRequestHandler,在没有 static/ 前缀的情况下)。

如果你想在以后添加图片而又不必重新构建和重新打包应用程序,最好使用绝对服务器路径,比如 C:\gallery\images 或者 /opt/gallery/images

英文:

If you package you application in a jar, it's no longer dependent on the source code.

If you start your application using java -jar ... in another folder or on another server, then new File(&quot;src/main/resources/static/images&quot;) will no longer work.

I think it will work when you execute java -jar ... in the root folder of your project, but that's probably not a long-term solution.

Maven considers the src/main/resources folder as an input folder for files that need to be included in the jar, so after packaging, those files will be available from java as getClass().getResource(&quot;/static/images/202008/1.jpg&quot;), and that's how they will be served in Spring Boot (using the ResourceHttpRequestHandler, without the static/ prefix).

If you want to add images later without having to rebuild and repackage your application, it's better to use an absolute server path like &quot;C:\gallery\images&quot; or &quot;/opt/gallery/images&quot;.

huangapple
  • 本文由 发表于 2020年9月1日 22:52:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/63690133.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定