Spring Boot 如何从Sping Boot 中提供静态HTML?

l2osamch  于 2023-05-17  发布在  Spring
关注(0)|答案(7)|浏览(471)

我从here运行了spring-boot-sample-web-static项目,对pom进行了以下更改

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

并添加了这个类,以提供来自相同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";
    }
}

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

我做错什么了吗?

9ceoxa92

9ceoxa921#

静态文件应该由资源提供,而不是由控制器提供。
Sping Boot 将自动添加位于以下任何目录中的静态Web资源:

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

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

wtlkbnrh

wtlkbnrh2#

在Sping Boot 中,/META-INF/resources//resources/static/public/目录可用于提供静态内容。
因此,您可以在resources/目录下创建static/public/目录,并将静态内容放在那里。它们将通过以下方式访问:http://localhost:8080/your-file.ext .(假设server.port为8080)
您可以使用application.properties中的spring.resources.static-locations自定义这些目录。
例如:

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

现在您可以使用resources/下的custom/文件夹来提供静态文件。
这也可以在Sping Boot 2中使用Java配置:

@Configuration
public class StaticConfig implements WebMvcConfigurer {

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

此混淆将custom目录的内容Map到http://localhost:8080/static/** URL。

nkkqxpd9

nkkqxpd93#

我正在使用:: Spring Boot :: (v2.0.4.RELEASE) with Spring Framework 5
Sping Boot 2.0需要Java 8作为最低版本。许多现有的API已经更新,以利用Java 8的功能,例如:接口上的默认方法、函数回调和新的API(如javax. time)。

静态内容

默认情况下,Sping Boot 从classpath中名为/static(或/public或/resources或/META-INF/resources)的目录或从ServletContext的根目录提供静态内容。它使用Spring MVC中的ResourceHttpRequestHandler,以便您可以通过添加自己的WebMvcConfigurer并重写addResourceHandlers方法来修改该行为。
默认情况下,资源Map在/**上,并位于/static目录中。但是您可以在我们的web上下文配置类中以编程方式自定义静态位置。

@Configuration @EnableWebMvc
public class Static_ResourceHandler implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // When overriding default behavior, you need to add default(/) as well as added static paths(/webapp).

        // src/main/resources/static/...
        registry
            //.addResourceHandler("/**") // « /css/myStatic.css
            .addResourceHandler("/static/**") // « /static/css/myStatic.css
            .addResourceLocations("classpath:/static/") // Default Static Loaction
            .setCachePeriod( 3600 )
            .resourceChain(true) // 4.1
            .addResolver(new GzipResourceResolver()) // 4.1
            .addResolver(new PathResourceResolver()); //4.1

        // src/main/resources/templates/static/...
        registry
            .addResourceHandler("/templates/**") // « /templates/style.css
            .addResourceLocations("classpath:/templates/static/");

        // Do not use the src/main/webapp/... directory if your application is packaged as a jar.
        registry
            .addResourceHandler("/webapp/**") // « /webapp/css/style.css
            .addResourceLocations("/");

        // File located on disk
        registry
            .addResourceHandler("/system/files/**")
            .addResourceLocations("file:///D:/");
    }
}
http://localhost:8080/handlerPath/resource-path+name
                    /static         /css/myStatic.css
                    /webapp         /css/style.css
                    /templates      /style.css
  • 在Spring中,每个请求都将通过DispatcherServlet。为了避免通过DispatcherServlet(前端控制器)请求静态文件,我们配置MVC静态内容。*

正如@STEEL所说,静态资源不应该通过Controller。Thymleaf是一个ViewResolver,它从控制器中获取视图名称,并将prefixsuffix添加到视图层。

xam8gpfp

xam8gpfp4#

如前所述,一些文件夹(/META-INF/resources/,/resources/,/static/,/public/)默认提供静态内容,控制器错误配置可能会破坏这种行为。
人们在@RestController注解中定义控制器的基本url,而不是在控制器顶部的@RequestMapping注解,这是一个常见的陷阱。
这是错误的:

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

    @PostMapping
    public String myPostMethod( ...) {

上面的例子会阻止你打开index.html。Spring在根上期望一个POST方法,因为myPostMethod被Map到“/”路径。
你必须使用这个代替:

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

    @PostMapping
    public String myPostMethod( ...) {
xtfmy6hx

xtfmy6hx5#

我不得不将thymeleaf依赖添加到pom.xml。如果没有这个依赖项,Sping Boot 就找不到静态资源。

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

szqfcxe26#

Sping Boot 中有三种类型的url:
1.相对于Web应用程序根:例如"/abc"
1.相对于classpath:例如"classpath:/abc"
1.相对于文件系统:例如"file:/abc"
回到主题,在Sping Boot 中,下面4个url中的静态资源可以通过"http://localhost:8080/${context root}/${your static resources}"访问。

classpath:/META-INF/resources
classpath:/resources
classpath:/static
classpath:/public
xxls0lw8

xxls0lw87#

您可以通过thymeleaf(参考:source
我假设你已经添加了Sping Boot 插件apply plugin: 'org.springframework.boot'和必要的buildscript
然后将thymeleaf添加到您的build.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')
}

让我们假设您已经在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";
      }

  }

就是这样!现在重启你的gradle服务器。./gradlew bootRun

相关问题