简体   繁体   English

使用 Spring MVC 和 Boot 刷新静态内容

[英]Refreshing static content with Spring MVC and Boot

I'm evaluating Spring MVC & Boot and AngularJs for building web applications.我正在评估用于构建 Web 应用程序的 Spring MVC & Boot 和 AngularJs。 I've run into the problem that when I make modifications to my static content (html, js, css), I have to restart the application every time.我遇到了一个问题,当我对我的静态内容(html、js、css)进行修改时,我每次都必须重新启动应用程序。 I hope there is a some way of solving that because restarting the whole application for static content changes is not efficient.我希望有某种方法可以解决这个问题,因为为静态内容更改重新启动整个应用程序效率不高。 Every other web app framework I've tried allows updating static content files on the fly(even just Spring MVC and plain old WAR application).我尝试过的所有其他 Web 应用程序框架都允许动态更新静态内容文件(甚至只是 Spring MVC 和普通的旧 WAR 应用程序)。

I've setup my project from "Building a RESTful Web Service with Spring Boot Actuator" guide ( http://spring.io/guides/gs/actuator-service/ ).我已经从“使用 Spring Boot Actuator 构建 RESTful Web 服务”指南( http://spring.io/guides/gs/actuator-service/ )设置了我的项目。 Basically it uses Spring Boot and MVC controllers to create a REST service.基本上它使用 Spring Boot 和 MVC 控制器来创建 REST 服务。 In addition, I've used "Consuming a RESTful Web Service with AngularJS" guide ( http://spring.io/guides/gs/consuming-rest-angularjs/ ) to build a frontend with AngularJS.此外,我已经使用“使用 AngularJS 使用 RESTful Web 服务”指南 ( http://spring.io/guides/gs/sumption-rest-angularjs/ ) 使用 AngularJS 构建前端。 It creates a web page that displays the response from the REST service.它创建一个网页,显示来自 REST 服务的响应。 The only change I've made is that the requests are made to my application instead of " http://rest-service.guides.spring.io/greeting ".我所做的唯一更改是向我的应用程序发出请求,而不是“ http://rest-service.guides.spring.io/greeting ”。 My static content is stored in "src/main/resources/public" folder.我的静态内容存储在“src/main/resources/public”文件夹中。 This setup works correctly except it doesn't reload static content.除了不重新加载静态内容外,此设置可以正常工作。

A recap of the original problem重述原始问题

I've run into the problem that when I make modifications to my static content (html, js, css), I have to restart the application every time我遇到了一个问题,当我对我的静态内容(html、js、css)进行修改时,我每次都必须重新启动应用程序

I had the same problem and finally solved it by adding我遇到了同样的问题,最后通过添加解决了它

<configuration>
    <addResources>true</addResources>
</configuration>

to spring-boot-maven-plugin in the pom.xml I got confused by this spring-boot-devtools thing, but it had no effect whatever I did.pom.xml中的spring-boot-maven-plugin我对这个 spring-boot-devtools 的东西感到困惑,但无论我做什么都没有效果。

My static content is stored in "src/main/resources/public" folder.我的静态内容存储在“src/main/resources/public”文件夹中。

Your path is just fine.你的路径很好。 src/main/resources/static is also fine. src/main/resources/static 也很好。

Ah ... I came across this issue too.啊……这个问题我也遇到了。

Instead of putting your static content in the classpath src/main/resources/public folder, put them in src/main/webapp , the same as you would any other Java web app.不要将您的静态内容放在类路径src/main/resources/public文件夹中,而是将它们放在src/main/webapp ,就像您将任何其他 Java Web 应用程序一样。 The embedded Tomcat will automatically reload them whenever they change.嵌入式 Tomcat 会在它们发生变化时自动重新加载它们。

As mentioned in the comments, the default configuration will not include the resources that are in src\\main\\webapp .如评论中所述,默认配置将不包括src\\main\\webapp的资源。 To get around this issue, you can just add the following to your pom.xml <build> node:要解决此问题,您只需将以下内容添加到 pom.xml <build>节点:

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>validate</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${basedir}/target/classes/static</outputDirectory>
                <resources>
                    <resource>
                        <directory>src/main/webapp</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

By using the resources plugin, you are able to do your local development by running the executable JAR:通过使用资源插件,您可以通过运行可执行 JAR 来进行本地开发:

java -jar target/.jar java -jar 目标/.jar

While that is running you can use Chrome Dev Tools or whatever IDE you like for modifying the files, without restarts.在运行时,您可以使用 Chrome Dev Tools 或任何您喜欢的 IDE 来修改文件,而无需重新启动。 However, whenever you run your build, then the package generated will include all of the files under src\\main\\webapp in src\\main\\resources\\static .但是,无论何时运行构建,生成的包都将包含src\\main\\resources\\static src\\main\\webapp下的所有文件。

The docs say "all modern IDEs allow reloading of static resources and usually also hot-swapping of Java class changes" ( https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#howto-hotswapping ).文档说“所有现代 IDE 都允许重新加载静态资源,通常还允许热交换 Java 类更改”( https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto。 html#howto-hotswapping )。 It's true.这是真的。 Eclipse does it more or less by default, and I'm not an IntelliJ user, but from what I understand you can configure it to build automatically as well. Eclipse 默认情况下或多或少会这样做,我不是 IntelliJ 用户,但据我所知,您也可以将其配置为自动构建。

A colleague and I came across this issue as well.我和一位同事也遇到了这个问题。 We found the answer in the IntelliJ documentation ...我们在IntelliJ 文档中找到了答案......

On the main menu, choose Run |在主菜单上,选择运行 | Reload Changed Classes重新加载更改的类

My solution (written in Kotlin but is quite obvious):我的解决方案(用 Kotlin 编写但很明显):

@Controller
class WebController : WebMvcConfigurerAdapter() {

    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
        System.getProperty("resources.local.path")?.let {
            registry.addResourceHandler("/**").addResourceLocations(it)
        }
    }
...
}

Main idea is you can add your own resource handler conditionally.主要思想是您可以有条件地添加自己的资源处理程序。 Eg if some system property is set ( resources.local.path ) then add resource location with value from the property.例如,如果设置了某些系统属性( resources.local.path ),则使用属性值添加资源位置。 Then you set this property in development with some reasonable value like '-Dresources.local.path=file:/Users/andrey/Projects/gsp-test/src/main/resources/static/'.然后您在开发中使用一些合理的值设置此属性,例如“-Dresources.local.path=file:/Users/andrey/Projects/gsp-test/src/main/resources/static/”。

Do not forget trailing slash.不要忘记尾部斜杠。

I am using 1.5.8.RELEASE.我正在使用 1.5.8.RELEASE。

It instantly updates my changes especially static files or jsp files.它会立即更新我的更改,尤其是静态文件或 jsp 文件。

If you are using Maven.如果您使用的是 Maven。 You need to add this in pom.xml你需要在 pom.xml 中添加这个

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>

And you have to start Spring Boot with this:你必须用这个启动 Spring Boot:

mvn clean spring-boot:run

Full example and more detail here https://www.surasint.com/spring-boot-with-auto-update-changed-files-example/完整示例和更多细节在这里https://www.surasint.com/spring-boot-with-auto-update-changed-files-example/

@eigil metioned addResources config for maven build. @eigil 提到了 maven 构建的addResources配置。 I'm using spring-boot-gradle-plugin in a gradle build, and I found this Spring Boot github issue , and the Spring Boot doc mentioned this option too .我在 gradle 构建中使用spring-boot-gradle-plugin ,我发现了这个Spring Boot github 问题,并且 Spring Boot 文档也提到了这个选项 Just add this directive to build.gradle and run Gradle task bootRun , then resource file refreshes immediately when saved.只需将此指令添加到 build.gradle 并运行 Gradle 任务bootRun ,然后资源文件在保存时立即刷新。 FYI.供参考。

我遇到了同样的问题,这里提出的解决方案似乎合乎逻辑,并且在 breif 中对我有用:1- ctrl+shift+A 2- 搜索注册表 3- 在打开的对话框中搜索“compiler.automake.allow.when.app”。正在运行”并检查它http://garywaddell.com/2015/11/20/spring-boot-intellij-idea-not-reloading-static-content/

对于 eclipse,您必须激活 Project -> "Build Automatically" 选项作为最低配置。

What I ended up using was Browsersync with grunt .我最终使用的是Browsersync 和 grunt browsersync and grunt watches your static resources on disk and updates the browser when you edit the files. browsersync 和 grunt 监视磁盘上的静态资源并在您编辑文件时更新浏览器。 It acts as a kind of proxy.它充当一种代理。 This way you can see changes in UI immediately without building or restarting anything.通过这种方式,您可以立即查看 UI 中的更改,而无需构建或重新启动任何内容。

Grunt, browsersync, spring boot and angularjs are configured for you if you use JHipster which I used to setup my project.咕噜,browsersync,弹簧引导和angularjs配置为你,如果你使用JHipster这在我以前设置我的项目。

Granted this requires a lot more tools than just an IDE and is a lot more complicated so I wouldn't recommend this for every project.当然,这需要更多的工具,而不仅仅是一个 IDE,而且要复杂得多,所以我不会为每个项目推荐这个。

spring-boot-devtools is not the solution to "hot deploy" of edited static htm/js spring-boot-devtools不是编辑静态 htm/js 的“热部署”的解决方案

I configured a web facet inside intellij so that when I use it to edit html/js file inside resources/static, intellij then knows to copy the updated file to ./target and the spring boot application I have launched inside the automatically displays that content我在 intellij 中配置了一个 web facet,这样当我使用它来编辑 resources/static 中的 html/js 文件时,intellij 就会知道将更新的文件复制到 ./target 并且我在其中启动的 spring boot 应用程序会自动显示该内容

see https://www.jetbrains.com/help/idea/2016.2/configuring-static-content-resources.htmlhttps://www.jetbrains.com/help/idea/2016.2/configuring-static-content-resources.html

The Java version of @viator 's answer: @viator 答案的 Java 版本:

@Configuration
class WebMvcConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/dist/*.js").addResourceLocations(
            "file:src/main/typescript/dist/"
        );
    }
}

You can do it by just adding one more dependency你可以通过添加一个更多的依赖来做到这一点

you Gradle你摇篮

compile group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '1.3.0.RELEASE'

In you Pom.xml在你的 Pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <version>1.3.0.RELEASE</version>
</dependency>

You have two possebilities how to serve static webcontent您有两种可能如何提供静态网页内容

  1. From the classpath (per default src/main/resources/static or src/main/resources/public or META-INF/resources/)从类路径(默认为 src/main/resources/static 或 src/main/resources/public 或 META-INF/resources/)
  2. From the file system (per default src/main/webapp)从文件系统(默认为 src/main/webapp)

If you pick solution 1) - you can safely copy the jar around as the static web content is within that jar.如果您选择解决方案 1) - 您可以安全地复制 jar,因为静态 Web 内容位于该 jar 中。 If you want that the server picks up changes, you need to do (auto)hotswapping.如果您希望服务器接收更改,则需要进行(自动)热交换。

If you pick solution 2) - everything will work out of the box, every change will be automatically picked up.如果您选择解决方案 2) - 一切都会开箱即用,每次更改都会自动进行。 HOWEVER - if you copy the final jar to a different location - things will stop working.但是 - 如果您将最终的 jar 复制到不同的位置 - 事情将停止工作。 That is unless you specify an absolute path in application.properties .除非您在application.properties指定绝对路径。 For example:例如:

spring.resources.static-locations=file:///C:/myspringbootapp/src/main/webapp

So solution 2) is easier but less portable.所以解决方案 2) 更容易但不太便携。 Solution 1) is portable but more difficult to use(ide config).解决方案 1) 是可移植的,但更难使用(ide 配置)。

For Spring Boot 2+ with gradle Kotlin dsl:对于带有 gradle Kotlin dsl 的 Spring Boot 2+:

tasks.bootRun {
    sourceResources(sourceSets.getAt(SourceSet.MAIN_SOURCE_SET_NAME))
}

thanks to @briskr's answer for the gradle dsl version :)感谢@briskr 对 gradle dsl 版本的回答:)

I had the same problem with live reloading of static contents in my SpringBoot porject: Now from various solutions posted in StackOverflow, I am able to get the solution.我在 SpringBoot 项目中实时重新加载静态内容时遇到了同样的问题:现在从 StackOverflow 中发布的各种解决方案中,我能够得到解决方案。 Following are the tools I used for development: IntelliJ Idea & Google Chrome in Ubuntu 18.04 I did the following:以下是我用于开发的工具: Ubuntu 18.04 中的 IntelliJ Idea 和 Google Chrome 我做了以下工作:

  1. Kept the templates folder in resourses folder itself.将模板文件夹保存在资源文件夹本身中。 (Some solutions I found it to be kept in webapp folder under the main, but I did not get the result) (一些解决方案我发现它保存在main下的webapp文件夹中,但我没有得到结果)
  2. Add this configuration添加这个配置
    <addResources>true</addResources>
    </configuration>

to spring-maven-plugin in your POM file.到 POM 文件中的 spring-maven-plugin。

3.Please don't forget to add this dependency to POM file 3.请不要忘记将此依赖项添加到POM文件中

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
  1. Add the Live Reload extension to your web browser.将 Live Reload 扩展添加到您的 Web 浏览器。

  2. Restart the server using ' mvn clean spring-boot:run ' (only then the changes will be reflected in the build).使用“ mvn clean spring-boot:run ”重新启动服务器(只有这样更改才会反映在构建中)。 During server startup you can see the message Live Server started at ....在服务器启动期间,您可以看到消息 Live Server started at ....

  3. Load the page using localhost:8080/... and click the LiveReload extension to connect it with the server.使用 localhost:8080/... 加载页面,然后单击 LiveReload 扩展以将其与服务器连接。

  4. Make any change to your static HTML file in the resources/ templates folder.对资源/模板文件夹中的静态 HTML 文件进行任何更改。 Save it and check the webbrowser again, it will be reflected there...保存并再次检查网络浏览器,它将反映在那里......

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

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