诡异得问题总是难以避免,发生了就有必要把经验留下来。在开发过程中很少见过当静态资源请求路径与接口请求路径前缀重叠得情况下发生异常,但就是遇到了:请求/hello/test.js /hello/testxxxx等路径 却能进入到接口/hello/test对应的方法内。遇到这样得问题应该怎么办呢?本文通过以下几个串起来得问题分享一下经验。
问题一:“springboot js文件请求路径 会被controller接收到”
在 Spring Boot 中,默认情况下,静态资源文件(如 JavaScript 文件)的请求路径不会被交由 Controller 处理。Spring Boot 的自动配置会将静态资源的请求路径与静态资源文件夹进行映射,以直接返回对应的静态资源文件,而不经过 Controller。
默认情况下,Spring Boot 将静态资源文件放置在以下目录中:
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
如果你将 JavaScript 文件放置在这些目录中的任何一个,并且请求路径与该文件的相对路径匹配,Spring Boot 将会直接返回该静态资源文件,而不会将请求交由 Controller。
如果你遇到了 JavaScript 文件的请求路径被 Controller 接收到的问题,可能是因为以下情况之一:
-
静态资源文件放置位置不正确:请确保你的 JavaScript 文件确实放置在 Spring Boot 默认的静态资源文件夹中(如 static 文件夹)。如果你将静态资源文件放置在其他位置,可能会导致请求被 Controller 接收到。
-
配置了自定义的静态资源处理器:如果你在 Spring Boot 中配置了自定义的静态资源处理器,可能会导致请求被 Controller 接收到。请检查你的配置,确保不会覆盖默认的静态资源处理器。
-
路径匹配问题:请确保你的 JavaScript 文件的请求路径与实际文件的相对路径匹配。如果路径不匹配,可能会导致请求被交由 Controller 处理。
请检查以上可能的原因,并根据具体情况进行调整。确保静态资源文件的位置正确,并且请求路径与实际文件的相对路径匹配。这样,请求就应该会直接返回对应的静态资源文件,而不会被 Controller 接收到。
问题二:“如何在 Spring Boot 中配置了自定义的静态资源处理器”
在 Spring Boot 中,你可以通过实现 WebMvcConfigurer
接口并重写 addResourceHandlers()
方法来配置自定义的静态资源处理器。
下面是一个示例,展示如何配置自定义的静态资源处理器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/custom/**")
.addResourceLocations("classpath:/custom/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
}
在上面的示例中,我们创建了一个名为 WebConfig
的配置类,并实现了 WebMvcConfigurer
接口。在 addResourceHandlers()
方法中,我们通过 ResourceHandlerRegistry
对象进行配置。
addResourceHandler("/custom/**")
指定了静态资源的 URL 路径模式,这里是/custom/**
。addResourceLocations("classpath:/custom/")
指定了静态资源文件的存放位置,这里是classpath:/custom/
,即 classpath 下的 custom 目录。setCachePeriod(3600)
设置了静态资源的缓存时间,这里是 3600 秒。resourceChain(true)
启用资源链。这将在开发环境中提供更好的性能,并启用对版本化资源的支持。addResolver(new PathResourceResolver())
添加了一个路径解析器,用于解析静态资源路径。
在上述配置中,我们将自定义的静态资源放置在 classpath 下的 custom 目录中。你可以根据自己的需求修改路径和其他属性。
配置完成后,你可以将静态资源文件放置在指定的位置,并通过 /custom/**
的路径模式来访问这些静态资源。
请确保将上述配置类正确地添加到你的 Spring Boot 项目中,以便生效并使用自定义的静态资源处理器。
问题三:“springboot开发得应用组件内自定义了静态资源处理器,依赖于这个组件得系统无法读取static下得文件,如何处理”
如果你基于 Spring Boot 开发的组件需要增加一个静态资源目录,同时又希望不影响依赖于这个组件的工程自有的静态资源配置,可以通过自定义配置类和资源处理器来实现。
下面是一种可行的方法:
- 在组件的配置类中,添加自定义的资源处理器,并指定自己的静态资源目录。
@Configuration
public class MyComponentConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mycomponent/**")
.addResourceLocations("classpath:/mycomponent-static/");
}
}
在上述示例中,我们将 /mycomponent/**
的请求路径映射到 classpath:/mycomponent-static/
目录下的静态资源。
- 在工程自有的配置类中,继承
WebMvcConfigurerAdapter
,并添加自己的静态资源配置。
@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app/**")
.addResourceLocations("classpath:/app-static/");
}
}
在上述示例中,我们将 /app/**
的请求路径映射到 classpath:/app-static/
目录下的工程自有的静态资源。
通过以上配置,组件和工程可以分别拥有自己的静态资源目录,并且互相不会影响。请求 /mycomponent/**
会访问组件的静态资源目录,而请求 /app/**
会访问工程自有的静态资源目录。
请根据你的实际需求修改路径和处理逻辑,并将以上配置类添加到对应的组件和工程中。这样,你就可以在不影响彼此的情况下,分别管理和访问各自的静态资源。
问题小结
最终发现是在应用组件中做了下面几件事导致异常一直不断:
1.组件内自定义了静态资源处理器
2.组件内自定义静态资源处理器时是通过集成org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport实现得,没有通过实现接口org.springframework.web.servlet.config.annotation.WebMvcConfigurer来实现。
3.配置静态资源处理器时写法上不一致,本应该是
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**")
.addResourceLocations("classpath:/ui/test/");
}
而写成了
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**")
.addResourceLocations("classpath:/ui/")
.addResourceLocations("file:" + filePath)
.setCachePeriod(3600);
}