java - not - Spring 4-addResourceHandlers no resuelve los recursos estáticos
spring resources static locations example (4)
Mi estructura de directorio de proyecto de primavera maven se muestra a continuación. Estoy usando la configuración basada en la anotación de Spring-4. Configuro los recursos como a continuación. Intenté muchas maneras que se sugieren en muchas preguntas de Stackoverflow y otros sitios web
Spring 4 carga de recursos estáticos
http://imwill.com/spring-mvc-4-add-static-resources-by-annotation/#.U5GZlXKs9i4
Pero los archivos jsp no pudieron cargar los recursos, todas las solicitudes de contenido estático devuelven el error 404. Intenté estas cosas en 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">
EDITAR: Estoy usando servlet 2.5 porque a partir de ahora no puedo actualizar mi proyecto de JBoss 5 a versiones superiores. JBoss5 no admite servlets 3, y ¿eso importa?
@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?
}
}
Es posible simplificar el URI de la página web solo para contener el nombre de archivo de un recurso:
<link href="bootstrap.css" rel="stylesheet" media="screen">
Una configuración adecuada podría ser la siguiente:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.css").addResourceLocations("/resources/css/");
}
Spring concatena la cadena ''/ resources / css /'' con cualquier nombre de archivo extraído del URI para identificar la ubicación real de un recurso.
Esto funcionó para mí. Archivos disponibles en /resources/js/select.js
. Ten en cuenta que no te falta la anotación @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/");
}
}
Supongo que es un poco tarde, sin embargo, recientemente tuve un problema similar. Después de varios días de lucha, finalmente resultó que mi DispatcherServlet no estaba configurado para manejar la solicitud, por lo tanto, nunca se buscaron los recursos. Así que espero que a otros les resulte útil esta respuesta.
Si el servlet despachador al que le da su clase de configuración anterior no se asigna a la raíz ("/") sino a una palabra superior (por ejemplo, "/ data /"), entonces puede enfrentar el mismo problema.
Supongamos que tengo una asignación como "/ data / *" para mi servlet despachador. Entonces mis llamadas se ven como
http://localhost:8080/myWebAppContext/data/command
y pensé que si tengo una asignación de recursos, por ejemplo, "/ content / ** / *", entonces tengo acceso a ella como
http://localhost:8080/myWebAppContent/content/resourcePath
pero no es verdad, debería usar
http://localhost:8080/myWebAppContent/data/content/resourcePath
en lugar. Esto no estaba claro para mí, y dado que la mayoría de las muestras usan la raíz "/" para el mapeo del servlet del operador, por lo tanto no fue un problema. Al considerarlo más tarde, debería haberlo sabido antes - / data / dice que el DispatcherServlet debe evaluar la llamada, y el contenido / le dice al servlet que un manejador de recursos es el "controlador".
Pero quiero dejar muy claro en mi interfaz (angularJs) si busco datos (a través de los servicios REST) o un contenido (devolviendo textos sin formato). Los datos provienen de una base de datos, pero el contenido proviene de archivos (por ejemplo, documentos PDF). Por lo tanto, decidí agregar dos asignaciones al servlet del despachador:
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 clase MidtierAppConfig está vacía, pero MidtierDispatcherConfig define los recursos estáticos:
@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/")
;
}
}
Ahora cuando quiero tener acceso a mi @ Controller, uso / data / prefix, y cuando quiero acceder a mis recursos, uso el / content / prefix. La advertencia es que si tengo una clase @RequestMapping ("/ app") que tiene un método @RequestMapping ("/ about"), tanto los datos / app / about y el contenido / app / about llamarán solo a ese método ( y sin intentarlo, creo que podría acceder a los recursos como / app / courses / whatEverPath también), porque el despachador escucha tanto "data /" como "content /", y analiza solo el resto de la url ("app / about "en ambos casos) para encontrar el @Controlador apropiado.
De todos modos, la solución actual que he alcanzado es satisfactoria para mí, así que la dejaré como está.
esto funcionó
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
y en los archivos jsp me referí a los recursos estáticos como
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">