Подтвердить что ты не робот

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?
     }

}

Project structure

4b9b3361

Ответ 1

это сработало,

   registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");

и в файлах jsp я ссылался на статические ресурсы, такие как

<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">

Ответ 2

Я думаю, что это немного поздно, однако я недавно столкнулся с подобной проблемой. После нескольких дней борьбы, наконец, выяснилось, что мой 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/")
        ;
    }
}

Теперь, когда я хочу получить доступ к моему контроллеру @, я использую префикс /data/prefix, и когда я хочу получить доступ к моим ресурсам, я использую префикс /content/. Предостережение заключается в том, что если у меня есть класс @RequestMapping ( "/app" ), который имеет метод @RequestMapping ( "/about" ), то оба метода data/app/about и content/app/about будут вызывать именно этот метод ( и, фактически, не пытаюсь, я думаю, что я мог бы получить доступ к ресурсам как /app/courses/whatEverPath тоже), потому что диспетчер прислушивается к "данным/" и "контенту/" и анализирует только остальную часть URL-адреса ( "app/about" в обоих случаях), чтобы найти правильный @Controller.

Несмотря на это, текущее решение, которое я достиг, для меня достаточно удовлетворительно, поэтому я оставлю его как есть.

Ответ 3

Это сработало для меня. Файлы доступны в /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/");
    }
}

Ответ 4

Можно упростить 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, чтобы определить фактическое местоположение ресурса.