简体   繁体   English

spring-boot 应用程序的嵌入式 Tomcat 目录列表

[英]Embedded Tomcat directory listing for spring-boot application

I have a spring boot application with embedded Tomcat.我有一个带有嵌入式 Tomcat 的 Spring Boot 应用程序。 I wanted to expose some images files & folders from a different location via tomcat directory listing.我想通过 tomcat 目录列表从不同的位置公开一些图像文件和文件夹。 So I added the below in my configuration file called所以我在我的配置文件中添加了以下内容

public class AppConfig extends WebMvcConfigurerAdapter

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:///xxx/yyy/images/");
    }
}

I can now access individual image(s), if I know the name.如果我知道名称,我现在可以访问单个图像。

Example: localhost:8080/images/file.jpg.示例:本地主机:8080/images/file.jpg。

But since the directory listing is false by default, I can't access the images listing through "localhost:8080/images/" to know the all the available images.但由于目录列表默认为 false,我无法通过“localhost:8080/images/”访问图像列表以了解所有可用图像。

I tried the below option to add the listings as well, but did not work.我也尝试了以下选项来添加列表,但没有用。

public class MyApplication implements ServletContextInitializer{

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.setInitParameter("listings", "true");
    }
}

Updated for Spring 2.1为 Spring 2.1 更新

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>  {

    @Value("${tomcat.file.base}")  // C:\\some\\parent\\child
    String tomcatBaseDir;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        TomcatContextCustomizer tomcatContextCustomizer = new TomcatContextCustomizer() {
            @Override
            public void customize(Context context) {
                String parentFolder = tomcatBaseDir.substring(0,tomcatBaseDir.lastIndexOf("\\"));
                String childFolder = tomcatBaseDir.substring(tomcatBaseDir.lastIndexOf("\\") + 1);
                context.setDocBase(parentFolder);
                Wrapper defServlet = (Wrapper) context.findChild("default");
                defServlet.addInitParameter("listings", "true");
                defServlet.addInitParameter("readOnly", "false");
                defServlet.addMapping("/"+ childFolder + "/*");
            }
        };
        factory.addContextCustomizers(tomcatContextCustomizer);

    }
}

In an identical way to SpringBoot Embedded Tomcat JSPServlet Options you can use an EmbeddedServletContainerCustomizer @Bean to look up the default servlet and configure its init parameters.以与SpringBoot Embedded Tomcat JSPServlet Options相同的方式,您可以使用EmbeddedServletContainerCustomizer @Bean来查找默认 servlet 并配置其初始化参数。

@Bean
public EmbeddedServletContainerCustomizer customizer() {
    return new EmbeddedServletContainerCustomizer() {

        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            if (container instanceof TomcatEmbeddedServletContainerFactory) {
                customizeTomcat((TomcatEmbeddedServletContainerFactory) container);
            }
        }

        private void customizeTomcat(TomcatEmbeddedServletContainerFactory tomcat) {
            tomcat.addContextCustomizers(new TomcatContextCustomizer() {

                @Override
                public void customize(Context context) {
                    Wrapper defServlet = (Wrapper) context.findChild("default");
                    defServlet.addInitParameter("listings", "true");
                }
            });
        }
    };
}

Kudos to Andy Wilkinson.向安迪·威尔金森致敬。

In springboot /** is mapped to ResourceHttpRequestHandler.在 springboot 中 /** 映射到 ResourceHttpRequestHandler。 The call never gets delegated to DefaultServlet for the listings to take effect.该调用永远不会委托给 DefaultServlet 以使列表生效。 I had to make two more adjustments to Mark's solution get it to work.我不得不对 Mark 的解决方案再做两次调整才能让它发挥作用。

  1. Add a different mapping to the DefaultServlet -> "/static/*"添加一个不同的映射到 DefaultServlet -> "/static/*"
  2. The docbase from where the static contents are served is a tmp folder.提供静态内容的文档库是一个 tmp 文件夹。 I had to set it to the folder where the static contents are present.我必须将其设置为存在静态内容的文件夹。

     public void customize(Context context) { context.setDocBase("../../../mytest"); Wrapper defServlet = (Wrapper) context.findChild("default"); defServlet.addInitParameter("listings", "true"); defServlet.addInitParameter("readOnly", "false"); defServlet.addMapping("/static/*"); }

    Deployment folder structure
    /myhome/mytest
    ----myapp.jar
    ----/tomcat/webapps
    ----/static
    --------All static files go here

    application.yml
    server :
     tomcat :
      basedir : tomcat

    Current working dir to run the app /myhome/mytest

    url to test : http://localhost:8080/static

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

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