简体   繁体   English

如何从 Spring Boot 提供静态 html?

[英]How can I serve static html from spring boot?

I ran the spring-boot-sample-web-static project from here , made this alteration to the pom我从这里运行了 spring-boot-sample-web-static 项目,对 pom 做了这个改动

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

And added this class to serve a duplicate page index2.html from the same static folder location:并添加了此类以从相同的static文件夹位置提供重复的页面 index2.html:

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Rester {

    @RequestMapping(value = "/rand", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    private RandomObj jsonEndpoint() {
        return new RandomObj();
    }

    @RequestMapping(value = "/tw")
    public String somePg() {
        return "index2";
    }
}

The json url works fine, but when I try to access localhost:8080/tw I get a blank page, and this error in the console: json url 工作正常,但是当我尝试访问 localhost:8080/tw 时,我得到一个空白页面,并且控制台中出现此错误:

2017-02-22 15:37:22.076 ERROR 21494 --- [nio-8080-exec-9] o.s.boot.web.support.ErrorPageFilter     : Cannot forward to error page for request [/tw] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

Am I doing something wrong?难道我做错了什么?

Static files should be served from resources, not from controller.静态文件应该由资源提供,而不是来自控制器。

Spring Boot will automatically add static web resources located within any of the following directories: Spring Boot 将自动添加位于以下任何目录中的静态 Web 资源:

 /META-INF/resources/ /resources/ /static/ /public/

refs:参考:
https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot
https://spring.io/guides/gs/serving-web-content/ https://spring.io/guides/gs/serving-web-content/

In Spring boot, /META-INF/resources/ , /resources/ , static/ and public/ directories are available to serve static contents.在 Spring Boot 中, /META-INF/resources//resources/static/public/目录可用于提供静态内容。

So you can create a static/ or public/ directory under resources/ directory and put your static contents there.所以你可以在resources/目录下创建一个static/public/目录并将你的静态内容放在那里。 And they will be accessible by: http://localhost:8080/your-file.ext .它们可以通过以下方式访问: http://localhost:8080/your-file.ext (assuming the server.port is 8080) (假设server.port是 8080)

You can customize these directories using spring.resources.static-locations in the application.properties .您可以使用application.properties中的spring.resources.static-locations自定义这些目录。

For example:例如:

spring.resources.static-locations=classpath:/custom/

Now you can use custom/ folder under resources/ to serve static files.现在您可以使用resources/下的custom/文件夹来提供静态文件。

Update:更新:

This is also possible using java config:这也可以使用 java 配置:

@Configuration
public class StaticConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/custom/");
    }
}

This confugration maps contents of custom directory to the http://localhost:8080/static/** url.此配置将custom目录的内容映射到http://localhost:8080/static/** url。

I am using :: Spring Boot :: (v2.0.4. RELEASE ) with Spring Framework 5我正在使用:: Spring Boot :: (v2.0.4. RELEASE ) with Spring Framework 5

Spring Boot 2.0 requires Java 8 as a minimum version. Spring Boot 2.0 要求 Java 8 作为最低版本。 Many existing APIs have been updated to take advantage of Java 8 features such as: default methods on interfaces, functional callbacks, and new APIs such as javax.time.许多现有 API 已更新以利用 Java 8 功能,例如:接口上的默认方法、函数式回调和新的 API(例如 javax.time)。

Static Content 静态内容

By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/ resources) in the classpath or from the root of the ServletContext.默认情况下,Spring Boot 提供来自类路径或 ServletContext 根目录中名为/static (或/public/resources/META-INF/ resources)的目录中的静态内容。 It uses the ResourceHttpRequestHandler from Spring MVC so that you can modify that behavior by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.它使用 Spring MVC 中的 ResourceHttpRequestHandler,因此您可以通过添加自己的WebMvcConfigurer并覆盖addResourceHandlers方法来修改该行为。

By default, resources are mapped on /** and located on /static directory.默认情况下,资源映射在/**并位于/static目录中。 But you can customize the static loactions programmatically inside our web context configuration class.但是您可以在我们的 Web 上下文配置类中以编程方式自定义静态位置。

http://localhost:8080/handlerPath/resource-path+name
                    /static         /css/myStatic.css
                    /webapp         /css/style.css
                    /templates      /style.css
 http://localhost:8080/handlerPath/resource-path+name /static /css/myStatic.css /webapp /css/style.css /templates /style.css

In Spring every request will go through the DispatcherServlet.在 Spring 中,每个请求都将通过 DispatcherServlet。 To avoid Static file request through DispatcherServlet(Front contoller) we configure MVC Static content .为了避免通过 DispatcherServlet(Front contoller) 请求静态文件,我们配置了 MVC 静态内容

As @STEEL said static resources should not go through Controller.正如@STEEL所说,静态资源不应该通过控制器。 Thymleaf is a ViewResolver which takes the view name form controller and adds prefix and suffix to View Layer. Thymleaf是一个 ViewResolver,它采用视图名称形式的控制器,并为视图层添加prefixsuffix

As it is written before, some folders (/META-INF/resources/, /resources/, /static/, /public/) serve static content by default, conroller misconfiguration can break this behaviour.正如之前所写,一些文件夹(/META-INF/resources/、/resources/、/static/、/public/)默认提供静态内容,控制器错误配置可能会破坏这种行为。

It is a common pitfall that people define the base url of a controller in the @RestController annotation, instead of the @RequestMapping annotation on the top of the controllers.人们在@RestController注释中定义控制器的基本url,而不是控制器顶部的@RequestMapping注释,这是一个常见的陷阱。

This is wrong:这是错误的:

@RestController("/api/base")
public class MyController {

    @PostMapping
    public String myPostMethod( ...) {

The above example will prevent you from opening the index.html.上面的例子会阻止你打开 index.html。 The Spring expects a POST method at the root, because the myPostMethod is mapped to the "/" path. Spring 期望在根有一个 POST 方法,因为myPostMethod被映射到“/”路径。

You have to use this instead:你必须改用这个:

@RestController
@RequestMapping("/api/base")
public class MyController {

    @PostMapping
    public String myPostMethod( ...) {

You can quickly serve static content in JAVA Spring-boot App via thymeleaf (ref: source )您可以通过thymeleaf在 JAVA Spring-boot App 中快速提供静态内容(参考:源代码

I assume you have already added Spring Boot plugin apply plugin: 'org.springframework.boot' and the necessary buildscript我假设您已经添加了 Spring Boot 插件apply plugin: 'org.springframework.boot'和必要的buildscript

Then go ahead and ADD thymeleaf to your build.gradle ==>然后继续前进,ADD thymeleafbuild.gradle ==>

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Lets assume you have added home.html at src/main/resources To serve this file, you will need to create a controller.假设您已在src/main/resources添加了home.html要提供此文件,您需要创建一个控制器。

package com.ajinkya.th.controller;

  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestMapping;

  @Controller
  public class HomePageController {

      @RequestMapping("/")
      public String homePage() {
        return "home";
      }

  }

Thats it !就是这样 ! Now restart your gradle server.现在重启你的 gradle 服务器。 ./gradlew bootRun

I had to add thymeleaf dependency to pom.xml.我不得不将 thymeleaf 依赖添加到 pom.xml。 Without this dependency Spring boot didn't find static resources.没有这个依赖,Spring boot 就找不到静态资源。

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

you can see the spring boot official example in the spring boot project, named spring-boot-sample-web-static . 你可以在spring boot项目中看到spring boot official示例,名为spring-boot-sample-web-static
First, you need extends SpringBootServletInitializer ; 首先,您需要extends SpringBootServletInitializer ;
Second, you need override the configure method in the start Application class 其次,您需要在启动Application类中override configure方法

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(Application.class);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM