出处:https://www.jianshu.com/p/861b8e9e2c79
我们知道在传统的Spring MVC项目中需要配置静态资源文件夹才能访问到静态文件,boot中同样如此,不过boot追求的少的配置,讲究开箱即用,所以boot给我们默认了几个静态文件路径
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
优先级:META-INF/resources > resources > static > public
首先来示范一下默认的静态资源文件夹,这里就不做优先级展示了,有兴趣的可以自己建立几个文件夹,然后放不同图片且同名的文件试一下,这里就一个static文件夹
image.png
做一个简单的freemarker模板,然后一个简单的控制器跳转,特别说明一点,做WEB项目的时候如果静态资源放在自己的工程静态目录下,而没有用文件服务器之类的东西,一般不会直接写相对路径,什么../xxx.jpg这种,喜欢标记项目路径,在freemarker中也有很多方式直接获取到路径,这里暂时两种,一种是用spring.ftl,一种是在application.properties配置文件中配置,这里先展示下效果,再说下用法。
package com.wzh.demo.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.wzh.demo.domain.UserBean;
import com.wzh.demo.service.IUserService;
@Controller
@RequestMapping("/user")
public class userTestController {
@RequestMapping("/img.do")
public String showImg(Model model)
{
model.addAttribute("imgName","test.png");
return "/test/img";
}
}
<#import "spring.ftl" as spring />
<!DOCTYPE html>
<html>
<head>
<title>MyHtml.html</title>
<meta name="keywords" content="keyword1,keyword2,keyword3">
<meta name="description" content="this is my page">
<meta name="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<body>
<img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
<img src="${request.contextPath }/imge/${imgName}" width="300px"/>
</body>
</html>
展示效果
image.png
在img标签的src 中用了两种路径的标记,一种是@spring.url,一种是request.contextPath。
@spring.url是基于spring-webmvc-4.3.6.RELEASE.jar中的spring.ftl文件实现的,其中调用rul宏的前缀可以自己定义,根据你import as 的别名
<#import "spring.ftl" as spring />
我们点开spring.ftl,可以找到定义url的方法,可以看出就是通过操作上下文获得的路径
<#--
* url
*
* Takes a relative URL and makes it absolute from the server root by
* adding the context root for the web application.
-->
<#macro url relativeUrl extra...><#if extra?? && extra?size!=0>${springMacroRequestContext.getContextUrl(relativeUrl,extra)}<#else>${springMacroRequestContext.getContextUrl(relativeUrl)}</#if></#macro>
<#--
image.png
第二种是配置文件中配置,本质也是通过上下文
spring.freemarker.request-context-attribute=request
同样的,在开发中因为这样那样的原因,我们需要自定义静态资源文件夹,下面就演示一下如何自定义静态资源文件夹,配置的方式有两种,一种是在代码中配置,还有一种是在application.properties中配置。
为了区别之前的static文件夹,新建一个webStatic文件夹
image.png
这个时候webStatic路径并没有配置为静态资源文件夹,因为web的安全机制,我们是无法直接通过下面这种路径方式去访问的,会报404
<img src="${request.contextPath }/pic/${imgName}" width="300px"/>
<img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
image.png
通过代码配置,在配置注解上这里使用@Configuration注解,注意不要用MVC的@EnableWebMvc, @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
package com.wzh.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Spring MVC 配置类,这里只配置静态资源
* 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
* @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 重写路径配置方法,添加自定义的路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/webStatic/** 访问都映射到classpath:/webStatic/ 目录下
registry.addResourceHandler("/webStatic/**").addResourceLocations("classpath:/webStatic/");
}
}
测试访问
image.png
测试发现,static文件夹下的资源和我们自定义的webStatic下的资源都能访问,并不影响Spring Boot的默认映射,可以同时使用。
不过如果如果我们将/webStatic/**
修改为 /**
与默认的相同时,则会覆盖系统的配置。
package com.wzh.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Spring MVC 配置类,这里只配置静态资源
* 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
* @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 重写路径配置方法,添加自定义的路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/** 访问都映射到classpath:/webStatic/ 目录下
registry.addResourceHandler("/**").addResourceLocations("classpath:/webStatic/");
}
}
因为都映射到了webStatic所以不需要文件夹前缀了
<img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
<img src="${request.contextPath }/pic/${imgName}" width="300px"/>
测试访问发现默认配置失效了,所以/**
的配置方式看实际项目情况权衡。
image.png
演示代码配置的路径只有一个,其实可以多次使用 addResourceLocations添加目录,优先级先添加的高于后添加的。
查看源码就可以看出addResourceHandler和addResourceLocations的参数是动参,可以同时添加多个参数。
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {
ResourceHandlerRegistration registration = new ResourceHandlerRegistration(this.applicationContext, pathPatterns);
this.registrations.add(registration);
return registration;
}
public ResourceHandlerRegistration addResourceLocations(String... resourceLocations) {
String[] var2 = resourceLocations;
int var3 = resourceLocations.length;
for(int var4 = 0; var4 < var3; ++var4) {
String location = var2[var4];
this.locations.add(this.resourceLoader.getResource(location));
}
return this;
}
演示下配置不同的访问配置一个路径和同一个路径配置多个文件夹,先新建3个文件夹img1,img2,img3
image.png
配置映射路径
package com.wzh.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Spring MVC 配置类,这里只配置静态资源
* 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
* @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 重写路径配置方法,添加自定义的路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/webStatic/** 访问都映射到classpath:/webStatic/ 目录下
registry.addResourceHandler("/webStatic/**").addResourceLocations("classpath:/webStatic/");
//将所有/img/**访问路径映射到img1,img2,img这个文件夹实际是不存在的,这里只是做个路径映射
registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img1/","classpath:/img2/");
//将所有/album1/**,/album2/**访问路径映射到img3,album这个文件夹实际是不存在的,这里只是做个路径映射
registry.addResourceHandler("/album1/**","/album2/**").addResourceLocations("classpath:/img3/");
}
}
页面
<img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
<img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
<img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
<img src="${request.contextPath }/img/test1.png" width="300px"/>
<img src="${request.contextPath }/img/test2.png" width="300px"/>
<img src="${request.contextPath }/album1/test3.png" width="300px"/>
<img src="${request.contextPath }/album2/test3.png" width="300px"/>
测试都能成功正常访问
image.png
通过配置文件配置访问路径,如果多个路径,和代码配置一样,逗号隔开
#SpringMVC 配置静态资源路径
spring.mvc.static-path-pattern=/img4/**
spring.resources.static-locations=classpath:/img4/,classpath:/img5/
页面
<img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
<img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
<img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
<img src="${request.contextPath }/img/test1.png" width="300px"/>
<img src="${request.contextPath }/img/test2.png" width="300px"/>
<img src="${request.contextPath }/album1/test3.png" width="300px"/>
<img src="${request.contextPath }/album2/test3.png" width="300px"/>
<img src="${request.contextPath }/img4/test4.png" width="300px"/>
<img src="${request.contextPath }/img4/test5.png" width="300px"/>
运行测试,发现第一张图片,也就是我们使用系统默认的static文件夹路径的404了,因为当在配置文件中配置了spring.mvc.static-path-pattern
就会使默认的路径失效。
image.png
同样,在项目比较大的时候我们处理静态文件一般有静态文件服务器,不过在项目比较小的时候文件和程序是放在一起的,这个时候一般有两种场景,第一种就是上面这种,项目文件夹在项目中,还有一种是在项目外面,通过绝对路径去访问。
#SpringMVC 配置静态资源路径
web.static-path=/Users/wzh/IdeaProjects/staticTest/
spring.mvc.static-path-pattern=/img4/**
spring.resources.static-locations=classpath:/img4/,classpath:/img5/,file:${web.static-path}
web.static-path
这个是自定义路径,在配置文件中自己定义的参数,名字可以自己取,因为配置的是路径,参数记得以/
结尾,特别说明下这个路径,和项目的运行系统是有关系的,如果是windows 要写成D:/XX/XX/
这种。spring.mvc.static-path-pattern
配置的是静态资源的访问路径,等同于代码中的addResourceHandler
方法。spring.resources.static-locations
配置的是映射的路径的正式路径,等同于代码中的addResourceLocations
方法,最末尾的file:${web.static-path}
之所有要加file:是因为指定的是一个具体的硬盘路径,其他的使用classpath指的是系统环境变量,如果需要在代码中配置绝对路径,只需要classpath改为file就可以了,其他的都不变。
以上就是在boot中配置静态资源文件夹的几种方式,这里做个记录。
作者:Harry_ZH_Wang
链接:https://www.jianshu.com/p/861b8e9e2c79
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。