Spring 4-addResourceHandlers не разрешают статические ресурсы
моя структура каталогов проекта Maven spring показана ниже. Я использую конфигурацию на основе аннотаций Spring-4. Я настраиваю ресурсы, как показано ниже. Я пробовал много способов, которые предлагаются во многих вопросах Stackoverflow и других веб-сайтах
Spring 4 загрузка статических ресурсов
http://imwill.com/spring-mvc-4-add-static-resources-by-annotation/#.U5GZlXKs9i4
но файлы jsp не смогли загрузить ресурсы, все статические запросы содержимого возвращают ошибку 404. Я пробовал эти вещи в JSP,
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
<link href="/resources/css/bootstrap.css" rel="stylesheet" media="screen">
<link href="css/bootstrap.css" rel="stylesheet" media="screen">
EDIT: я использую сервлет 2.5, потому что на данный момент я не могу обновить свой проект с JBoss 5 до более высоких версий. JBoss5 не поддерживает сервлеты 3, и это имеет значение?
@Configuration
@ComponentScan("com.mgage.mvoice")
public class MyAppWebConfig extends WebMvcConfigurerAdapter {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// I tried these many combinations separately.
ResourceHandlerRegistration resourceRegistration = registry
.addResourceHandler("resources/**");
resourceRegistration.addResourceLocations("/resources/**");
registry.addResourceHandler("/css/**").addResourceLocations("/css/**");
registry.addResourceHandler("/img/**").addResourceLocations("/img/**");
registry.addResourceHandler("/js/**").addResourceLocations("/js/**");
registry.addResourceHandler("/resources/**")
.addResourceLocations("classpath:/resources/");
// do the classpath works with the directory under webapp?
}
}
4 ответов
это работает,
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
и в файлах jsp я ссылался на статические ресурсы, такие как
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
Я думаю, что это немного поздно, но я столкнулся с подобной проблемой совсем недавно. После нескольких дней борьбы, наконец, оказалось, что мой DispatcherServlet не был настроен для обработки запроса, поэтому ресурсы никогда не искали. Поэтому я надеюсь, что другие найдут этот ответ полезным.
если сервлет диспетчера, которому вы даете свой класс конфигурации выше, сопоставлен не с корнем ( " / " ), а с верхним словом (например, "/data/"), то вы можете столкнуться с тем же проблема.
предположим, что у меня есть отображение как "/data/*" для моего сервлета диспетчера. Так что мои звонки выглядят как
http://localhost:8080/myWebAppContext/data/command
и я подумал, что если у меня есть отображение ресурсов, например " / content/**/*", то у меня есть доступ к нему как
http://localhost:8080/myWebAppContent/content/resourcePath
но это неправда, я должен использовать
http://localhost:8080/myWebAppContent/data/content/resourcePath
вместо. Для меня это было неясно, и поскольку большинство образцов используют корень "/" для отображения сервлета диспетчера, поэтому это не было проблемой. После рассмотрения позже я должен был знать это раньше - /data / говорит, что DispatcherServlet должен оценивать вызов, а контент/ сообщает сервлету, что обработчик ресурсов является "контроллером".
но я хочу, чтобы в моем интерфейсе (angularJs) было очень ясно, ищу ли я данные (через службы REST) или контент (возвращая простые тексты). Данные поступают из базы данных, но содержимое поступает из файлов (например, pdf docs). Поэтому я решил добавить два сопоставления к диспетчеру сервлет:
public class MidtierWebConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(MidtierAppConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(MidtierDispatcherConfig.class);
Dynamic netskolaDispatcher = servletContext.addServlet(
"dispatcher",
new DispatcherServlet(dispatcherContext)
);
netskolaDispatcher.setLoadOnStartup(1);
netskolaDispatcher.addMapping("/data/*");
netskolaDispatcher.addMapping("/content/*");
}
}
класс MidtierAppConfig пуст, но класс MidtierDispatcherConfig определяет статические ресурсы:
@Configuration
@ComponentScan("my.root.package")
@EnableWebMvc
public class MidtierDispatcherConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/courses/**/*")
.addResourceLocations("/WEB-INF/classes/content/")
;
}
}
теперь, когда я хочу иметь доступ к моему @Controller, я использую/ data / prefix, и когда я хочу получить доступ к моим ресурсам, я использую /content/ prefix. Предостережение заключается в том, что если у меня есть класс @RequestMapping("/app"), который имеет метод @RequestMapping("/about"), то и данные / app / about и контент / app / about будут вызывать только этот метод (и без фактической попытки, я думаю, я мог бы получить доступ к ресурсам как /app/courses / whatEverPath тоже), потому что диспетчер прослушивает как "данные/", так и "контент/" и анализирует только остальную часть url ("app/about" в обоих случаях), чтобы найти правильный @Controller.
независимо от того, текущее решение, которого я достиг, достаточно удовлетворительно для меня, поэтому я оставлю его как есть.
это работает для меня. Файлы доступны по адресу /resources/js/select.js
. Следите, чтобы вы не пропустили @EnableWebMvc
Примечание....
@EnableWebMvc
@EnableTransactionManagement
public class ApplicationContextConfig extends WebMvcConfigurerAdapter {
@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
можно упростить URI веб-страницы, чтобы просто содержать имя файла ресурса:<link href="bootstrap.css" rel="stylesheet" media="screen">
Соответствующая конфигурация может быть следующей:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.css").addResourceLocations("/resources/css/");
}
Spring объединяет строку/resources/css/ с любым именем файла, извлеченным из URI, чтобы определить фактическое местоположение ресурса.