简体   繁体   English

如何在Spring Boot Embedded tomcat中维护外部静态HTML文件?

[英]How to service external static HTML files in Spring Boot Embedded tomcat?

I'm new to Spring framework and Spring Boot. 我是Spring框架和Spring Boot的新手。
I've implemented a very simple RESTful Spring Boot web application. 我已经实现了一个非常简单的RESTful Spring Boot Web应用程序。
You can see the nearly full source code in another question: Spring Boot: How to externalize JDBC datasource configuration? 您可以在另一个问题中看到几乎完整的源代码: Spring Boot:如何外部化JDBC数据源配置?

How can the app service external static HTML, css js files? app如何服务外部静态HTML,css js文件?
For example, the directory structure may be as follows: 例如,目录结构可能如下:

MyApp\
   MyApp.jar (this is the Spring Boot app that services the static files below)
   static\
       index.htm
       images\
           logo.jpg
       js\
           main.js
           sub.js
       css\
           app.css
       part\
           main.htm
           sub.htm

I've read the method to build a .WAR file that contains static HTML files, but since it requires rebuild and redeploy of WAR file even on single HTML file modification, that method is unacceptable. 我已经阅读了构建包含静态HTML文件的.WAR文件的方法,但由于它需要重建和重新部署WAR文件,即使在单个HTML文件修改时,该方法也是不可接受的。

An exact and concrete answer is preferable since my knowledge of Spring is very limited. 一个确切而具体的答案是可取的,因为我对Spring的了解非常有限。

I see from another of your questions that what you actually want is to be able to change the path to static resources in your application from the default values. 我从另一个问题中看到,您真正想要的是能够从默认值更改应用程序中静态资源的路径。 Leaving aside the question of why you would want to do that, there are several possible answers. 撇开为什么要这样做的问题,有几个可能的答案。

  • One is that you can provide a normal Spring MVC @Bean of type WebMvcConfigurerAdapter and use the addResourceHandlers() method to add additional paths to static resources (see WebMvcAutoConfiguration for the defaults). 一个是您可以提供类型为WebMvcConfigurerAdapter的普通Spring MVC @Bean ,并使用addResourceHandlers()方法向静态资源添加其他路径(请参阅WebMvcAutoConfiguration以获取默认值)。
  • Another approach is to use the ConfigurableEmbeddedServletContainerFactory features to set the servlet context root path. 另一种方法是使用ConfigurableEmbeddedServletContainerFactory功能来设置servlet上下文根路径。
  • The full "nuclear option" for that is to provide a @Bean definition of type EmbeddedServletContainerFactory that set up the servlet container in the way you want it. 完整的“核选项”是提供类型为EmbeddedServletContainerFactory@Bean定义,它以您希望的方式设置servlet容器。 If you use one of the existing concrete implementations they extend the Abstract* class that you already found, so they even have a setter for a property called documentRoot . 如果您使用现有的具体实现之一,它们会扩展您已经找到的Abstract*类,因此它们甚至可以为名为documentRoot的属性设置setter。 You can also do a lot of common manipulations using a @Bean of type EmbeddedServletContainerCustomizer . 您还可以使用类型为EmbeddedServletContainerCustomizer@Bean进行大量常见操作。

Is enough if you specify '-cp .' 如果指定'-cp'就足够了。 option in command 'java -jar blabla.jar' and in current directory is 'static' directory 命令'java -jar blabla.jar'中的选项和当前目录中的'static'目录

Take a look at this Dave Syer's answer implementation. 看看这个 Dave Syer的答案实现。

You can set the document root directory which will be used by the web context to serve static files using ConfigurableEmbeddedServletContainer.setDocumentRoot(File documentRoot) . 您可以使用ConfigurableEmbeddedServletContainer.setDocumentRoot(File documentRoot) Web上下文将用于提供静态文件的文档根目录。

Working example: 工作范例:

package com.example.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.File;
import java.nio.file.Paths;

@Configuration
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);

    private final Environment env;
    private static final String STATIC_ASSETS_FOLDER_PARAM = "static-assets-folder";
    private final String staticAssetsFolderPath;

    public WebConfigurer(Environment env, @Value("${" + STATIC_ASSETS_FOLDER_PARAM + ":}") String staticAssetsFolderPath) {
        this.env = env;
        this.staticAssetsFolderPath = staticAssetsFolderPath;
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        if (env.getActiveProfiles().length > 0) {
            log.info("Web application configuration, profiles: {}", (Object[]) env.getActiveProfiles());
        }
        log.info(STATIC_ASSETS_FOLDER_PARAM + ": '{}'", staticAssetsFolderPath);
    }

    private void customizeDocumentRoot(ConfigurableEmbeddedServletContainer container) {
        if (!StringUtils.isEmpty(staticAssetsFolderPath)) {
            File docRoot;
            if (staticAssetsFolderPath.startsWith(File.separator)) {
                docRoot = new File(staticAssetsFolderPath);
            } else {
                final String workPath = Paths.get(".").toUri().normalize().getPath();
                docRoot = new File(workPath + staticAssetsFolderPath);
            }
            if (docRoot.exists() && docRoot.isDirectory()) {
                log.info("Custom location is used for static assets, document root folder: {}",
                        docRoot.getAbsolutePath());
                container.setDocumentRoot(docRoot);
            } else {
                log.warn("Custom document root folder {} doesn't exist, custom location for static assets was not used.",
                        docRoot.getAbsolutePath());
            }
        }
    }

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        customizeDocumentRoot(container);
    }

}

Now you can customize your app with command line and profiles ( src\\main\\resources\\application-myprofile.yml ): 现在,您可以使用命令行和配置文件( src\\main\\resources\\application-myprofile.yml )自定义您的应用src\\main\\resources\\application-myprofile.yml

> java -jar demo-0.0.1-SNAPSHOT.jar --static-assets-folder="myfolder"
> java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=myprofile

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

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