我的maven spring项目目录结构如下所示。我正在使用基于Spring-4注释的配置。我配置如下的资源。我尝试了许多Stackoverflow问题和其他网站中提出的方法
Spring 4 loading static resources
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">
编辑:我正在使用servlet 2.5,因为到目前为止我无法将我的项目从JBoss 5升级到更高版本。 JBoss5不支持servlet 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?
}
}
答案 0 :(得分:17)
这很有用,
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
在jsp文件中我引用了静态资源,如
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
答案 1 :(得分:13)
我想这有点晚了,但是最近我遇到了类似的问题。经过几天的摔跤,最后发现我的DispatcherServlet没有配置为处理请求,因此从未查找过资源。所以我希望其他人会觉得这个答案很有用。
如果您给上面的配置类的调度程序servlet不是映射到根(“/”)而是映射到顶部字(例如“/ data /”),那么您可能会面临同样的问题。 / p>
假设我的调度程序servlet的映射为“/ data / *”。所以我的电话看起来像
http://localhost:8080/myWebAppContext/data/command
我认为如果我有资源映射,例如“/ content / ** / *”,然后我可以访问它
http://localhost:8080/myWebAppContent/content/resourcePath
但事实并非如此,我应该使用
http://localhost:8080/myWebAppContent/data/content/resourcePath
代替。这对我来说并不清楚,并且由于大多数示例使用根“/”作为调度程序servlet的映射,因此它不是问题。稍后考虑我应该早点知道 - / data /告诉DispatcherServlet应该评估调用,content /告诉servlet资源处理程序是“控制器”。
但我想在我的前端(angularJs)中清楚地表明我是在寻找数据(通过REST服务)还是内容(返回纯文本)。数据来自数据库,但内容来自文件(例如pdf文档)。因此,我决定在调度程序servlet中添加两个映射:
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 /前缀,当我想访问我的资源时,我使用/ content /前缀。需要注意的是,如果我有一个@RequestMapping(“/ app”)类具有@RequestMapping(“/ about”)方法,那么data / app / about和content / app / about都会调用该方法(并且没有实际尝试我猜我可能会访问资源/ app / courses / whatEverPath),因为调度程序同时侦听“data /”和“content /”,并仅分析其余的url(“app / about “在这两种情况下)找到合适的@Controller。
无论如何,我所达到的当前解决方案对我来说足够令人满意,所以我会保持原样。
答案 2 :(得分:6)
这对我有用。 /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/");
}
}
答案 3 :(得分:1)
我正在使用Spring Boot 2.2.1以及“ spring-boot-starter-web”和“ spring-boot-starter-tomcat”。就我而言,当我使用空的“ classpath:/ ”
时,Spring Boot仅能找到“ / resources / ”文件夹。我的文件夹结构:
我的代码:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("classpath:/");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
使用浏览器,我可以找到任何文件,例如:
答案 4 :(得分:0)
可以简化网页的URI只是为了包含资源的文件名:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.css").addResourceLocations("/resources/css/");
}
适当的配置可能如下所示:
{{1}}
Spring将'/ resources / css /'字符串与从URI中提取的任何文件名连接起来,以识别资源的实际位置。