Вопрос или проблема
Я переношу приложение на Spring Boot v3.3.4, но мои статические ресурсы не обслуживаются Spring Boot. У меня есть статические файлы (html, css, js, png и т.д.) в src\main\resources\static
. Вот отрывок из моих логов, когда я пытаюсь загрузить URL /index.html
.
[DEBUG] 2024-11-02 14:16:57.789 [https-jsse-nio-8443-exec-1] c.f.a.u.CustomRequestLoggingFilter - Перед запросом [GET /index.html, заголовки=[host:"localhost:8443", connection:"keep-alive", pragma:"no-cache", cache-control:"no-cache", sec-ch-ua:""Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"", sec-ch-ua-mobile:"?0", sec-ch-ua-platform:""Windows"", upgrade-insecure-requests:"1", user-agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/129.0.0.0 Safari/537.36", accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", sec-fetch-site:"none", sec-fetch-mode:"navigate", sec-fetch-user:"?1", sec-fetch-dest:"document", accept-encoding:"gzip, deflate, br, zstd", accept-language:"en-US,en;q=0.9", cookie:"Idea-2ba4f510=04bef4d7-875e-4491-bdd6-da8a4b98ccba; JSESSIONID=465E301E3CAD061A3DA5584DE01C1C59"]]
[WARN ] 2024-11-02 14:16:57.791 [https-jsse-nio-8443-exec-1] o.s.w.s.PageNotFound - Нет сопоставления для GET /index.html
[WARN ] 2024-11-02 14:16:57.791 [https-jsse-nio-8443-exec-1] o.s.w.s.PageNotFound - Нет конечной точки GET /index.html.
[DEBUG] 2024-11-02 14:16:57.792 [https-jsse-nio-8443-exec-1] c.f.a.u.CustomRequestLoggingFilter - После запроса [GET /index.html, заголовки=[host:"localhost:8443", connection:"keep-alive", pragma:"no-cache", cache-control:"no-cache", sec-ch-ua:""Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"", sec-ch-ua-mobile:"?0", sec-ch-ua-platform:""Windows"", upgrade-insecure-requests:"1", user-agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/129.0.0.0 Safari/537.36", accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", sec-fetch-site:"none", sec-fetch-mode:"navigate", sec-fetch-user:"?1", sec-fetch-dest:"document", accept-encoding:"gzip, deflate, br, zstd", accept-language:"en-US,en;q=0.9", cookie:"Idea-2ba4f510=04bef4d7-875e-4491-bdd6-da8a4b98ccba; JSESSIONID=465E301E3CAD061A3DA5584DE01C1C59"]]
Насколько я понимаю, ресурсы/static должны автоматически обслуживаться без дополнительной конфигурации. Но что-то в моем порте могло отключить это? У меня не так много настроек в конфигурациях.
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.groovy().cache(true);
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add( new JsonConverter() );
converters.add( new FileMessageConverter() );
converters.add( new BufferedImageHttpMessageConverter());
}
@Bean
public FilterRegistrationBean<SpringBootUrlRewriteFilter> urlRewriteFilter(@Value(SpringBootUrlRewriteFilter.CONFIG_LOCATION) Resource config) {
FilterRegistrationBean<SpringBootUrlRewriteFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new SpringBootUrlRewriteFilter(config));
registration.addUrlPatterns("/*");
registration.setName("urlRewriteFilter");
registration.setOrder(SecurityProperties.DEFAULT_FILTER_ORDER-5);
registration.setDispatcherTypes(DispatcherType.FORWARD,DispatcherType.REQUEST);
return registration;
}
@Bean
public AngularViewTemplateProcessor createAngularViewTemplateProcessor() {
return new AngularViewTemplateProcessor();
}
}
И AppConfig
@Configuration
@ComponentScan(basePackages = "com.fuseanalytics")
@PropertySources(value = {
@PropertySource(value={"classpath:application.properties"}),
@PropertySource(value = {"classpath:server.${spring.profiles.active:dev}.properties"}),
@PropertySource(value={"file:${server.data.home}/credentials/credentials.properties"}),
@PropertySource(value={"classpath:wro.${spring.profiles.active:dev}.properties"})
})
public class AppConfig {
@Bean
public BCryptPasswordEncoder getBcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Как мне отладить это? Я прослеживал код Spring, пытаясь понять, что вызывает отсутствие обслуживания ресурсов, но безуспешно. Поэтому я думаю, что существует более простой способ устранения неполадок. Есть идеи?
Ответ или решение
Причины, по которым статические ресурсы не обслуживаются в Spring Boot
При портировании вашего приложения Spring на Spring Boot версии 3.3.4 может возникнуть проблема с обслуживанием статических ресурсов. Давайте рассмотрим возможные причины и пути их устранения.
Проверка структуры проекта
Важно удостовериться, что статические ресурсы действительно находятся в нужной директории. Статические файлы (HTML, CSS, JS, изображение и т.д.) должны располагаться в следующей структуре:
src/main/resources/static
Если ваша структура папок отличается, это может привести к ошибкам в обслуживании ресурсов. Например, если файлы находятся в src/main/resources/public
или src/main/resources/META-INF/resources
, Spring Boot также сможет их обслуживать, но нужно удостовериться, что вы обращаетесь к ним правильно.
Автоматическая конфигурация Spring Boot
Spring Boot автоматически настраивает обработку статических ресурсов без дополнительной конфигурации, если вы не отключили эту функциональность. Однако использование аннотации @EnableWebMvc
, как в вашем случае, может вызвать проблемы. Эта аннотация отключает автоматическую конфигурацию MVC Spring Boot, что и может стать основной причиной того, что статические ресурсы не доступны.
Решение:
Удалите аннотацию @EnableWebMvc
из вашего конфигурационного класса WebConfig
:
@Configuration
public class WebConfig implements WebMvcConfigurer {
// ваш код
}
Это позволит Spring Boot самостоятельно настраивать обработку статических ресурсов.
Конфигурация фильтров
Вы добавили SpringBootUrlRewriteFilter
, который применяется ко всем URL /*
. Это может вызвать проблемы с доступом к статическим ресурсам, если фильтр не обрабатывает правильные маршруты. Убедитесь, что ваш фильтр не влияет на запросы к статическим ресурсам.
Рекомендация:
Попробуйте исключить маршруты, которые относятся к статическим файлам, добавив в конфигурацию URL-исключения:
registration.addUrlPatterns("/*");
registration.setUrlPatterns(Arrays.asList("/*", "!/static/*"));
Логи и отладка
Из логов видно, что Spring Boot не может найти привязку для запроса GET /index.html
. Убедитесь также, что в конфигурации вашего приложения нет других настроек, касающихся обработки статических ресурсов. Проверьте наличие дополнительных конфигурационных файлов, которые могут переопределять настройки.
Дополнительные шаги для отладки:
-
Логи на уровне DEBUG: Убедитесь, что у вас включены логи на уровне DEBUG для Spring Web, добавив в
application.properties
следующий параметр:logging.level.org.springframework.web=DEBUG
-
Запрос статических ресурсов напрямую: Попробуйте напрямую по безопасности с запросом к статическому ресурсу, например, к CSS или изображениям, чтобы определить, возникают ли проблемы только с HTML.
-
Проверка ответов сервера: Используйте инструменты разработчика в браузере (F12), чтобы посмотреть, какие запросы отправляются и какие ошибки получает браузер.
Вывод
Следуя этим рекомендациям, вы сможете выявить и устранить проблемы с обслуживанием статических ресурсов в вашем приложении на Spring Boot. Если проблема все еще сохраняется, рекомендуется проверить актуальность зависимости Spring Boot в pom.xml
или build.gradle
, чтобы исключить возможные конфликты версий.