静态资源中的 Spring Boot 2.6 和 Angular

2024-04-21

我的问题非常类似于this https://stackoverflow.com/questions/40769200/configure-spring-boot-for-spa-frontend已经提出并回答过的问题,但不是 100% 最新的。

我们使用 Chris Gaskill 的解决方案相当长一段时间,它非常适合我们,因为我们想要重定向包含多个路径段的请求(即/foo/bar)

从 Spring Boot 2.4 开始,Boot 使用PathPatternParser而不是AntPathMatcher,其中前者不支持**不再在模式的开头(see docs https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping-uri-templates).

是否有其他解决方案来获得相同的行为?您使用什么将所有与其他内容不匹配的请求重定向到index.htmlAngular 应用程序的?

这是转发请求的控制器的代码。

@Controller
class SpaRoutingController {

  @GetMapping("/**/{path:[^\\.]*}", headers = "X-Requested-With!=XMLHttpRequest")
  fun forward(): String? {
      return "forward:/"
  }
}

我宁愿去配置一个解决方案WebMvcConfigurer反而。请参阅下面的代码。

Maven 配置

Maven 配置指导frontend-maven-plugin构建角度并将构建的内容复制到target/static目录,以便它在最终构建的 WAR 和 JAR 中可用。然后我另外配置一个WebMvcConfigurer在 JAR / WAR 的静态目录中查找资源,如果找到 - 将其发送到客户端,否则重定向到 index.html。

<plugin>
        <artifactId>maven-clean-plugin</artifactId>
        <version>${maven-clean-plugin.version}</version>
        <configuration>
          <filesets>
            <fileset>
              <directory>src/main/webapp</directory>
              <includes>
                <include>*.js</include>
                <include>*.txt</include>
                <include>*.html</include>
                <include>*.css</include>
                <include>*.map</include>
                <include>*.json</include>
                <include>*.ico</include>
                <followSymlinks>false</followSymlinks>
              </includes>
            </fileset>
            <fileset>
              <directory>src/main/webapp/assets</directory>
              <includes>
                <include>**</include>
                <followSymlinks>false</followSymlinks>
              </includes>
            </fileset>
          </filesets>
        </configuration>
        <executions>
          <execution>
            <id>auto-clean</id>
            <phase>initialize</phase>
            <goals>
              <goal>clean</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>process-resources</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/classes/static</outputDirectory>
              <includeEmptyDirs>true</includeEmptyDirs>
              <resources>
                <resource>
                  <directory>${basedir}/src/main/${angular.project.name}/dist/${angular.project.name}</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>com.github.eirslett</groupId>
        <artifactId>frontend-maven-plugin</artifactId>
        <version>1.8.0</version>
        <configuration>
          <workingDirectory>src/main/${angular.project.name}</workingDirectory>
        </configuration>
        <executions>
          <execution>
            <id>install node and npm</id>
            <goals>
              <goal>install-node-and-npm</goal>
            </goals>
            <phase>generate-resources</phase>
            <configuration>
              <nodeVersion>v14.16.1</nodeVersion>
            </configuration>

          </execution>
          <execution>
            <id>npm build angular</id>
            <goals>
              <goal>npm</goal>
            </goals>
            <phase>generate-resources</phase>
            <configuration>
              <arguments>run build:prod</arguments>
            </configuration>
          </execution>
        </executions>
      </plugin>

MVC配置

在这里,您尝试查找静态目录中是否存在资源,如果不存在,则将其重定向到index.html。

您可能需要根据您的要求更改源位置。

@Configuration
public class ApplicationWebMvcConfiguration implements WebMvcConfigurer {
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {

    registry.addResourceHandler("/**")
            .addResourceLocations("classpath:/static/")
            .resourceChain(true)
            .addResolver(new PathResourceResolver() {
              @Override
              protected Resource getResource(String resourcePath, Resource location)
                  throws IOException {

                Resource requestedResource = location.createRelative(resourcePath);
                if (requestedResource.exists() && requestedResource.isReadable()) {
                  return requestedResource;
                }

                return new ClassPathResource("/static/index.html");

              }
            });

  }

}

您应该为路径 / 或“”的极端情况添加额外的控制器

@Controller
public class StaticContentController {

    private final ResourceLoader resourceLoader;

    public StaticContentController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
    @ResponseBody
    public Resource serveStaticContent() {
        // Load and return your static HTML file
        return resourceLoader.getResource("classpath:/static/index.html");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态资源中的 Spring Boot 2.6 和 Angular 的相关文章

随机推荐