it-swarm-eu.dev

Spring 4 - addResourceHandlers nie rozwiązuje statycznych zasobów

Moja struktura katalogu maven spring jest pokazana poniżej. Używam konfiguracji opartej na adnotacjach Spring-4. Konfiguruję zasoby, jak poniżej. Próbowałem wielu sposobów, które są sugerowane w wielu pytaniach Stackoverflow i innych stronach internetowych 

Wiosna 4 ładowanie statycznych zasobów

http://imwill.com/spring-mvc-4-add-static-resources-by-annotation/#.U5GZlXKs9i4

Jednak pliki jsp nie mogły załadować zasobów, wszystkie żądania statycznej zawartości zwracają błąd 404. Próbowałem tych rzeczy w 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">

EDYCJA: Używam serwletu 2.5, ponieważ od teraz nie mogę uaktualnić mojego projektu z JBoss 5 do wyższych wersji. JBoss5 nie obsługuje serwletów 3 i ma to znaczenie?

@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

24

to zadziałało, 

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

w plikach jsp odniosłem się do statycznych zasobów, takich jak 

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

Myślę, że jest trochę za późno, ale ostatnio miałem do czynienia z podobnym problemem. Po kilku dniach zmagań okazało się, że mój DispatcherServlet nie został skonfigurowany do obsługi żądania, dlatego zasoby nigdy nie zostały sprawdzone. Mam więc nadzieję, że inni uznają tę odpowiedź za przydatną.

Jeśli serwlet dyspozytora, któremu podałeś powyższą klasę konfiguracji, nie jest mapowany do katalogu głównego („/”), ale do najwyższego Worda (np. „/ Data /”), możesz napotkać ten sam problem.

Załóżmy, że mam mapowanie jako „/ data/*” dla mojego serwletu dyspozytora. Tak wyglądają moje połączenia

http://localhost:8080/myWebAppContext/data/command

i pomyślałem, że jeśli mam mapowanie zasobów, np. „/ content/**/*”, wtedy mam do niego dostęp jako

http://localhost:8080/myWebAppContent/content/resourcePath

ale to nieprawda, powinienem użyć

http://localhost:8080/myWebAppContent/data/content/resourcePath

zamiast. Nie było to dla mnie jasne, a ponieważ większość próbek używa roota „/” do mapowania serwletu dispatchera, nie było to więc problemem. Po rozważeniu tego powinienem wiedzieć wcześniej -/data/mówi, że DispatcherServlet powinien ocenić wywołanie, a content/mówi serwletowi, że program obsługi zasobów jest „kontrolerem”.

Ale chcę bardzo wyraźnie zaznaczyć w moim interfejsie (angularJs), czy szukam danych (za pośrednictwem usług REST), czy treści (zwracających zwykłe teksty). Dane pochodzą z bazy danych, ale treść pochodzi z plików (np. Dokumentów PDF). Dlatego postanowiłem dodać dwa mapowania do serwletu dispatchera:

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/*");
}

}

Klasa MidtierAppConfig jest pusta, ale MidtierDispatcherConfig definiuje zasoby statyczne:

@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/")
        ;
    }
}

Teraz, gdy chcę mieć dostęp do moich kontrolerów @, używam prefiksu/data /, a kiedy chcę uzyskać dostęp do moich zasobów, używam prefiksu/content /. Zastanawia się, że jeśli mam klasę @RequestMapping ("/ app"), która ma metodę @RequestMapping ("/ about"), to zarówno data/app/about, jak i content/app/about będą wywoływać tę właśnie metodę ( i bez próbowania zgaduję, że mogę też uzyskać dostęp do zasobów jako/app/courses/whatEverPath), ponieważ dyspozytor słucha zarówno „data /”, jak i „content /” i analizuje tylko resztę adresu URL („app/about” „w obu przypadkach”, aby znaleźć odpowiedni kontroler @.

Niezależnie od tego, obecne rozwiązanie, które osiągnąłem, jest dla mnie wystarczająco zadowalające, więc zostawię je bez zmian.

12
Ivan Ketler

To działało dla mnie. Pliki dostępne w /resources/js/select.js. Uważaj, że nie brakuje adnotacji @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/");
    }
}
6
kundan

Możliwe jest uproszczenie identyfikatora URI strony internetowej tylko po to, aby zawierał nazwę pliku zasobu:
<link href="bootstrap.css" rel="stylesheet" media="screen">
.__ Odpowiednia konfiguracja może wyglądać następująco: 

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("*.css").addResourceLocations("/resources/css/");
}

Spring konkatenuje łańcuch „/ resources/css /” z dowolną nazwą pliku wyodrębnioną z URI w celu określenia rzeczywistej lokalizacji zasobu.

0
beemaster