Spring 4 - AddresourceHandlers che non risolvono le risorse statiche
-
22-12-2019 - |
Domanda
La mia struttura della directory del progetto Spring Maven è mostrata di seguito. Sto usando la configurazione basata sull'annotazione di Spring-4. Configurare le risorse come di seguito. Ho provato molti modi che sono suggeriti in molte domande di stackoverflow e altri siti Web
Spring 4 Caricamento delle risorse statiche
http://imwill.com/ Spring-MVC-4-Add-Static-Risorse-By-Annotation / #. u5gzlxks9i4
Ma i file JSP non possono caricare le risorse, tutte le richieste di contenuto statico restituiscono l'errore 404. Ho provato queste cose in 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">
.
Modifica: sto usando servlet 2.5 perché a partire da ora non posso aggiornare il mio progetto da JBoss 5 a versioni più alte. JBoss5 non supporta i servlet 3 e fanno questo problema?
@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?
}
}
.
Soluzione
Questo ha funzionato,
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
.
E nei file JSP mi sono riferito alle risorse statiche come
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
. Altri suggerimenti
Immagino sia un po 'in ritardo, tuttavia stavo affrontando un problema simile solo di recente. Dopo diversi giorni di wrestling, infine si è scoperto che il mio DispatcheRServlet non è stato configurato per gestire la richiesta, quindi le risorse non sono mai state alzati in alto. Quindi spero che gli altri troveranno questa risposta utile.
Se il servlet del dispatcher a cui si fornisce la classe di configurazione sopra è mappato non alla radice ("/") ma a una parola superiore (ad es. "/ Data /"), è possibile affrontare lo stesso problema. < / P >.
Supponiamo di avere una mappatura come "/ dati / *" per il mio servlet del dispatcher. Quindi le mie chiamate sembrano
http://localhost:8080/myWebAppContext/data/command
.
E ho pensato che se ho una mappatura delle risorse ad es. "/ Content / ** / *", quindi ho accesso ad esso come
http://localhost:8080/myWebAppContent/content/resourcePath
.
Ma non è vero, dovrei usare
http://localhost:8080/myWebAppContent/data/content/resourcePath
.
invece. Questo non era chiaro per me, e dal momento che la maggior parte dei campioni utilizza la radice "/" per la mappatura del servlet del dispatcher, quindi non era un problema lì. Dopo aver considerato in seguito avrei dovuto conoscerlo in precedenza - / Data / indica che il DispatcheRServlet deve valutare la chiamata e il contenuto / indica al servlet che un gestore di risorse è il "controller".
Ma voglio renderlo molto chiaro nel mio frontend (Angularjs) sia che io cerchi i dati (tramite i servizi di riposo) o un contenuto (Thising Tranks). I dati provengono da un database, ma il contenuto proviene da file (E.G. Docs PDF). Pertanto, ho deciso di aggiungere due mappature al servlet del dispatcher:
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/*");
}
}
.
La classe MidtierappConfig è vuota, ma il MidtierDispatcherConfig definisce le risorse statiche:
@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/")
;
}
}
.
Ora quando voglio avere accesso al mio controller, uso il / dati / prefisso, e quando voglio accedere alle mie risorse, uso il / contenuto / prefisso. L'avvertenza è che se ho una classe @requestmapping ("/ app") che ha un metodo @requestmapping ("/ circa"), quindi sia i dati / app / circa e il contenuto / app / circa chiamerà solo quel metodo ( e senza effettivamente provare immagino che potrei accedere alle risorse come / app / corsi / qualunque percorso anche), poiché il dispatcher elenca a "Data /" e "Content /", e analizza solo il resto dell'URL ("App / About "In entrambi i casi) trovare il corretto @Controller.
A prescindere, la soluzione attuale che ho raggiunto è abbastanza soddisfacente per me, quindi lo lascerò così com'è.
Questo ha funzionato per me.File disponibili su /resources/js/select.js
.Attenzione che non ti manca Annotazione @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/");
}
}
. È possibile semplificare l'URI della pagina Web solo per contenere il nome file di una risorsa:
<link href="bootstrap.css" rel="stylesheet" media="screen">
.
Una configurazione appropriata potrebbe essere come la seguente:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.css").addResourceLocations("/resources/css/");
}
.
Spring Concatenas '/ Risorse / CSS /' String con qualsiasi nome file estratto dall'URI per identificare la posizione effettiva di una risorsa.