简体   繁体   English

Spring Boot 不会将文件夹请求映射到 `index.html` 文件

[英]Spring boot doesn't map folder requests to `index.html` files

I've got static folder with following structure:我有以下结构的static文件夹:

index.html索引.html
docs/index.html文档/index.html

Spring Boot correctly maps requests / to index.html . Spring Boot 正确地将 requests /映射到index.html But it doesn't map /docs/ request to /docs/index.html ( /docs/index.html request works correctly).但它不会将/docs/请求映射到/docs/index.html/docs/index.html请求工作正常)。

How to map folder/subfolder requests to appropriate index.html files?如何将文件夹/子文件夹请求映射到适当的index.html文件?

You can manually add a view controller mapping to make this work:您可以手动添加视图控制器映射来完成这项工作:

@Configuration
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/docs").setViewName("redirect:/docs/");
        registry.addViewController("/docs/").setViewName("forward:/docs/index.html");
    super.addViewControllers(registry);
    }
}

The first mapping causes Spring MVC to send a redirect to the client if /docs (without trailing slash) gets requested.如果/docs (没有尾部斜杠)被请求,第一个映射会导致 Spring MVC 向客户端发送重定向。 This is necessary if you have relative links in /docs/index.html .如果您在/docs/index.html有相关链接,则这是必要的。 The second mapping forwards any request to /docs/ internally (without sending a redirect to the client) to the index.html in the docs subdirectory.第二个映射在内部将任何对/docs/请求(不向客户端发送重定向)转发到docs子目录中的index.html

After Java 8 introduced Default Methods in Interfaces , WebMvcConfigurerAdapter has been deprecated in Spring 5 / Spring Boot 2 .在 Java 8在接口中引入默认方法之后WebMvcConfigurerAdapter在 Spring 5/Spring Boot 2 中已被弃用

Using it will now raise the warning :使用它现在会引发 警告

The type WebMvcConfigurerAdapter is deprecated不推荐使用 WebMvcConfigurerAdapter 类型

Hence, to make @hzpz's solution work again, we need to change it as follows:因此,要使@hzpz 的解决方案再次起作用,我们需要对其进行如下更改:

@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/docs").setViewName("redirect:/docs/");
        registry.addViewController("/docs/").setViewName("forward:/docs/index.html");
    }
}

It's not Spring Boot mapping to index.html it's the servlet engine (it's a welcome page).它不是 Spring Boot 到 index.html 的映射,它是 servlet 引擎(这是一个欢迎页面)。 There's only one welcome page (per the spec), and directory browsing is not a feature of the containers.只有一个欢迎页面(根据规范),并且目录浏览不是容器的功能。

This one will always try to match requestPath + /index.html if static resource is not found:如果没有找到静态资源,这个将总是尝试匹配requestPath + /index.html

import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolverChain;

@Configuration
public class ResourceHandlerConfig implements WebMvcConfigurer {

  static class IndexFallbackResourceResolver extends PathResourceResolver{
    @Override
    protected Resource resolveResourceInternal(HttpServletRequest request, String requestPath,
        List<? extends Resource> locations, ResourceResolverChain chain) {
      Resource resource = super.resolveResourceInternal(request, requestPath, locations, chain);
      if(resource==null){
        //try with /index.html
        resource = super.resolveResourceInternal(request, requestPath + "/index.html", locations, chain);
      }
      return resource;
    }
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
        .addResourceHandler("/**")
        .addResourceLocations("classpath:/static/")
        //first time resolved, that route will always be used from cache
        .resourceChain(true)
        .addResolver(new IndexFallbackResourceResolver());
  }
}

Spring boot show index.html by default. Spring boot 默认显示 index.html。

but index.html should be in /resource/static or /public但 index.html 应该在 /resource/static 或 /public

example:例子:

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-static

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

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