直接映射到静态页面
当访问某个地址的时候,都会优先检查是否有静态页面,如果没有,才去controller里面查找。
例如,访问 localhost:8080/test.html 时,它就会先查找如下4个位置
- classpath:/META-INF/resources/
- classpath:/public/
- classpath:/resources/
- classpath:/ static/
注意:不在这4个位置,即使在 resources 目录下,默认也是无法直接访问的
因此,当不配置任何 controller 时,5-6.html 是访问不了的,但1-4.html 却可以正常访问。
Spring指定路径映射到静态页面
如果想改变静态页面的访问路径,可以将静态资源通过流直接返回给前端。
例如,规定路径中包含有 /test/ 的地址,即访问资源目录下的 test 文件夹下的路径,如果没有文件名,设置默认访问 index.html。创建一个 StaticResourceController.java
@Controller
public class StaticResourceController {
private static final String PATH_TEST = "test/";
@RequestMapping(PATH_TEST + "**")
public void getHtml(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getRequestURI();
String[] arr = uri.split(PATH_TEST);
String resourceName = "index.html";
if (arr.length > 1) {
resourceName = arr[1];
}
// String path1 = StaticResourceController.class.getResource(null).getPath();
String path2 = StaticResourceController.class.getResource("").getPath();
String path3 = StaticResourceController.class.getResource(".").getPath();
String path4 = StaticResourceController.class.getResource("/").getPath();
// System.out.println("path1 = " + path1);
System.out.println("path2 = " + path2);
System.out.println("path3 = " + path3);
System.out.println("path4 = " + path4);
String url = StaticResourceController.class.getResource("/").getPath() + PATH_TEST + resourceName;
FileReader reader = null;
BufferedReader br = null;
try {
File file = new File(url);
if (file.exists()) {
reader = new FileReader(file);
br = new BufferedReader(reader);
StringBuilder sb = new StringBuilder();
for (String line = br.readLine(); line != null; line = br.readLine()) {
sb.append(line);
}
response.getOutputStream().write(sb.toString().getBytes());
response.flushBuffer();
} else {
//如果返回错误信息为中文,则一定药设置编码,否则显示问号
response.setCharacterEncoding("utf8");
response.sendError(404, "页面未找到");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(br != null) br.close();
if(reader != null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对于 getResource() 方法
- 参数不能为空,会报空指针异常
- 参数为空串,等价于点号,指的是当前类的路径
- 参数为斜杠(/),指的是根目录
可以看到,编译之后会把 resources 目录下的文件和 类的根路径放置在同级的位置
至于 resources 目录的文件名,可以通过 pom.xml 中的设置进行改变
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
Spring Boot 指定路径映射到静态页面
无论是通过代码,还是通过配置文件,设置之后,都会覆盖默认的那 4个路径(classpath:/META-INF/resources/,classpath:/public/,classpath:/resources/,classpath:/ static/),导致无法访问
通过代码
WebMvcConfigurerAdapter 已经被废弃了,查看源码可知,由于Java8 的新特性,可以在接口前面加一个 default 关键词,来为接口创建一个默认的实现,这样实现该接口的类就不用实现全部接口了。
因此,这里直接实现 WebMvcConfigurer 即可
/**
* An implementation of {@link WebMvcConfigurer} with empty methods allowing
* subclasses to override only the methods they're interested in.
*
* @author Rossen Stoyanchev
* @since 3.1
* @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
* possible by a Java 8 baseline) and can be implemented directly without the
* need for this adapter
*/
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { …… }
Spring Boot 通过注解@Configuration 来实现 IOC(控制反转)和 DI(依赖注入),将管理权交给 Spring 容器。
@Configuration
public class ResourceConf implements WebMvcConfigurer {
/**
* 静态资源处理器
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//路径前缀,可填写多个值
registry.addResourceHandler("test/**")
//映射到的资源路径(路径后的斜杠不能省略,否则无法访问)
.addResourceLocations("classpath:/test/", "classpath:/templates/");
}
// /** 解决跨域问题 **/
// public void addCorsMappings(CorsRegistry registry) {}
// /** 添加拦截器 **/
// public void addInterceptors(InterceptorRegistry registry) {}
// /** 这里配置视图解析器 **/
// public void configureViewResolvers(ViewResolverRegistry registry) {}
// /** 配置内容裁决的一些选项 **/
// public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
// /** 视图跳转控制器 **/
// public void addViewControllers(ViewControllerRegistry registry) {}
// /** 静态资源处理 **/
// public void addResourceHandlers(ResourceHandlerRegistry registry) {}
// /** 默认静态资源处理器 **/
// public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
}
通过配置文件
properties 和 yml,仅需要设置一个即可。这里只是做个示范
如果两个都设置,则仅 properties 生效。
application.properties
spring.mvc.static-path-pattern = /test/**
spring.resources.static-locations = classpath:/test/, classpath:/templates/
application.yml
spring:
mvc:
static-path-pattern: /test/**
resources:
static-locations: classpath:/test2/, classpath:/templates/
static-path-pattern:表示访问模式,默认为 /** ,如果有多个可以通过逗号分隔
static-locations:静态资源目录,如果有多个可以通过逗号分隔,默认的静态路径为 classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/
当多个静态资源目录下,有名字相同的文件时,会按照设置的顺序进行排查,返回第一个找到的。