Spring Boot 可执行 jar 无法访问索引页面

Posted

技术标签:

【中文标题】Spring Boot 可执行 jar 无法访问索引页面【英文标题】:Springboot executable jar can not access index page 【发布时间】:2018-05-19 11:50:58 【问题描述】:

我用 springboot、restapi 和 angularjs 创建了一个应用程序。我将把这个项目变成可执行的 jar。但是当我做java -jar patchinit.jar 时,它不会重新加载索引页面。它给了

Whitelabel 错误页面(出现意外错误(类型=未找到, status=404 没有可用的消息)

尝试http://localhost:8080/

我错过了什么吗?我几乎绝望地尝试了一切..

POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ama.ist</groupId>
    <artifactId>patchinit</artifactId>
    <packaging>jar</packaging>
    <version>0.0.1</version>
    <name>patchinit Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
    </parent>


    <properties>
        <java.version>1.7</java.version>
    </properties>

    <dependencies>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!-- <scope>provided</scope> -->
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
<!--            <scope>provided</scope> -->
        </dependency>

        <dependency>
            <groupId>org.tmatesoft.svnkit</groupId>
            <artifactId>svnkit</artifactId>
            <version>1.7.8</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>patchinit</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>
</project>

Webapplication.java

package com.ama.ist;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.web.bind.annotation.RequestMapping;

@SpringBootApplication
public class WebApplication extends SpringBootServletInitializer 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) 
        return application.sources(WebApplication.class);
    

    public static void main(String[] args) throws Exception 
        SpringApplication.run(WebApplication.class, args);
    


HelloController.java

package com.ama.ist.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController 

    @RequestMapping("/")
    String index() 
        return "index";
    


index.html

<!DOCTYPE html>
<html ng-app="MyApp">
<head>

<link rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.5/angular-material.min.css">



</head>
<body>

    <div class="container">

        <div class="row">

            <div class="col-md-4 jumbotron">
                <div class="col-md-12 dialog-demo-content">
                    <div ui-view="newPatch"></div>
                </div>
            </div>


            <div class="col-md-8 ">

                <div ui-view="svntab"></div>

            </div>

        </div>
    </div>



    <!--    <div class="container" class="md-padding" ng-cloak> -->
    <!--        <div class="row"> -->
    <!--            <div class="col-md-3 dialog-demo-content"> -->
    <!--                <div ui-view="newPatch"></div> -->
    <!--            </div> -->

    <!--            <div class="col-md-2"></div> -->



    <!--            <div class="col-md-3"> -->
    <!--                <div ui-view="svntab"></div> -->
    <!--            </div> -->
    <!--        </div> -->
    <!--    </div> -->




    <!-- *************************   SCRIPTS  ********************************** -->
    <script src="https://code.angularjs.org/1.5.8/angular.js"></script>
    <script
        src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>

    <script
        src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script
        src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">

    </script>
    <script
        src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
    <script
        src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
    <script
        src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
    <script
        src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>


    <script src="js/app.js"></script>
    <script src="js/patch.controller.js"></script>
    <script src="js/svn.controller.js"></script>


</body>

</html>

这是springboot的输出

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.5.RELEASE)

2017-12-05 19:54:09.019  INFO 480 --- [           main] com.ama.ist.WebApplication               : Starting WebApplication on ISTL55310 with PID 480 (C:\Erkan\eclipse-workspace-new\patchinit\target\classes started by erkan.erkisi in C:\Erkan\eclipse-workspace-new\patchinit)
2017-12-05 19:54:09.022  INFO 480 --- [           main] com.ama.ist.WebApplication               : No active profile set, falling back to default profiles: default
2017-12-05 19:54:09.063  INFO 480 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1ce2a846: startup date [Tue Dec 05 19:54:09 EET 2017]; root of context hierarchy
2017-12-05 19:54:10.335  INFO 480 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-12-05 19:54:10.345  INFO 480 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2017-12-05 19:54:10.347  INFO 480 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.33
2017-12-05 19:54:10.987  INFO 480 --- [ost-startStop-1] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2017-12-05 19:54:10.994  INFO 480 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-12-05 19:54:10.994  INFO 480 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1933 ms
2017-12-05 19:54:11.468  INFO 480 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2017-12-05 19:54:11.471  INFO 480 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-12-05 19:54:11.471  INFO 480 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-12-05 19:54:11.471  INFO 480 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-12-05 19:54:11.471  INFO 480 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'requestContextFilter' to: [/*]
2017-12-05 19:54:11.639  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1ce2a846: startup date [Tue Dec 05 19:54:09 EET 2017]; root of context hierarchy
2017-12-05 19:54:11.697  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/]" onto java.lang.String com.ama.ist.controller.HelloController.index()
2017-12-05 19:54:11.698  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/resource]" onto public java.util.Map<java.lang.String, java.lang.Object> com.ama.ist.controller.PatchController.home()
2017-12-05 19:54:11.698  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/mk],methods=[POST]" onto public org.springframework.http.ResponseEntity<?> com.ama.ist.controller.PatchController.createFolder(com.ama.ist.model.Patch)
2017-12-05 19:54:11.701  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/localfolders],methods=[GET]" onto public org.springframework.http.ResponseEntity<java.util.List<com.ama.ist.model.Folder>> com.ama.ist.controller.SvnController.getlocalFolders(com.ama.ist.model.User)
2017-12-05 19:54:11.702  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/svnfolders],methods=[GET]" onto public org.springframework.http.ResponseEntity<java.util.List<com.ama.ist.model.Folder>> com.ama.ist.controller.SvnController.getFolders(com.ama.ist.model.User)
2017-12-05 19:54:11.703  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/error]" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-12-05 19:54:11.704  INFO 480 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/error],produces=[text/html]" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-12-05 19:54:11.716  INFO 480 --- [           main] o.s.w.s.c.a.WebMvcConfigurerAdapter      : Adding welcome page: ServletContext resource [/index.html]
2017-12-05 19:54:11.736  INFO 480 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2017-12-05 19:54:11.745  INFO 480 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-05 19:54:11.745  INFO 480 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-05 19:54:11.778  INFO 480 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-05 19:54:11.878  INFO 480 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-12-05 19:54:11.945  INFO 480 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-12-05 19:54:11.949  INFO 480 --- [           main] com.ama.ist.WebApplication               : Started WebApplication in 3.254 seconds (JVM running for 3.827)

Project Structure as an image

【问题讨论】:

我以前试过但没有运气:( 试过但没用 嗨,您检查了以下解决方案 我会在2小时内尝试并通知您 它有效,但我也只将 index.hmtl 文件移动到资源/模板,其余 html 页面移动到资源/静态。我在静态文件夹中创建了 js 文件夹并移到其中的 js 文件。谢谢你。但是为什么 webapp 文件夹不起作用?为什么我们将 html 和 js 文件移动到模板中。当您在 ide (eclipse) 上运行时,它与 webapp 文件夹结构一样工作 【参考方案1】:

终于找到了解决办法。我可以通过在 pom 中添加 thymeleaf 依赖项来解决此问题

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

什么是百里香?

Thymeleaf 是一个 Java 库。它是一个XML/XHTML/HTML5 模板引擎,能够将一组转换应用于模板文件,以显示您的应用程序生成的数据和/或文本。

您的 html 文件中需要更正一项:

<link rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.5/angular-material.min.css">

确保使用结束标记&lt;/link&gt; 关闭此标记&lt;link&gt;。否则你会得到以下错误

出现意外错误(类型=内部服务器错误, 状态=500)。异常解析文档:template="index",第 12 行 - 第 3 栏

项目结构

【讨论】:

以上是关于Spring Boot 可执行 jar 无法访问索引页面的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot JSF可执行JAR找不到xhtml文件

Spring Boot 可执行 jar “无效或损坏的 jar 文件”

Spring Boot 上传 BootRepackage 可执行 Jar

聚合maven+spring-boot打包可执行jar

Spring Boot 无法访问依赖 jars 类路径中的资源

使用 Spring-Boot 创建一个简单的 JAR 而不是可执行的 JAR