SpringBoot访问静态文件的几种方法
- TOC
{:toc}
我以前写过一个使用DefaultServlet
实现下载的博客springboot 添加defaultServlet实现更好的文件下载功能 ,这篇文章是对这类问题的多种解法讲解。
目的
将图片存储在f:\\test
文件夹或其子文件夹下,实现访问http://localhost/static/1.jpg
网页上展示图片,访问http://localhost/download/1.jpg
浏览器下载图片。
方法1
请参考这篇文章的实现, springboot 添加defaultServlet实现更好的文件下载功能,原理是配置一个DefaultServlet
来处理所有静态资源请求。
方法2
原理使用Controller
拦截掉静态资源的请求,转发到DefaultServlet
。
配置Controller如下
,使用RequestMapping
分开配置,处理下载的/download/**
和处理展示的 /static/**
分开。
他们俩的唯一区别是,/download/**
手动设置了响应头,在此设置的content-type
,后面就不会被设置了,否则会根据资源类型自适应content-type
。
调用ServletContext
的Dispatcher
做转发。
1 |
|
上面的做法是在Controller
里面拦截请求,再请求转发到DefaultServlet
上,这样就不用配置DefaultServlet
的ServletMapper
了,使用SpringMvc
来管理路径问题。
这种方法默认defaultServlet
被配置(Tomcat
环境下是会被配置的)。
方法3
本方法使用Spring
的实现,即使底层用的不是Tomcat
,Spring
也能将这种差异屏蔽。
SpringBoot
默认会按顺序扫描以下目录的静态资源文件,这是SpringBoot
默认配置的,默认拦截路径是/**
。
1 |
|
写一个类继承WebMvcConfigurationSupport
,实现addResourceHandlers
方法
1 |
|
要注意的点:
资源在外部文件夹下的路径写法要以
file:
开头,以/
结尾,如file:D:/test/
访问
classpath
的资源,路径要以classpath:/
开头,以/
结尾,如classpath:/static/
访问
第三方jar
内部的静态文件,配置是classpath:/META-INF/resources/
像下面这样配置两个相同的路径,则后面覆盖前面的。
registry.addResourceHandler("/classpath/**").addResourceLocations("file:D:/test") registry.addResourceHandler("/classpath/**").addResourceLocations("file:E:/zz")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- **切记不要配置成`classpath:/`,这会导致`resources`文件夹暴露出来,导致配置文件泄露**
但是这种方法并不能实现文件下载,能识别出`content-type`的如图片会自动打开在浏览器上,不能识别的资源才会调用浏览器下载。
# 关于自动配置
- 自动配置
一旦继承了`WebMvcConfigurationSupport`类,即使不重写`addResourceHandlers`类,自动配置的5个路径就失效了。所以就不能访问静态文件了。
- `swagger-ui`的静态资源
在使用`swagger-ui`时,它的原理是将`swagger-ui.html`页面打包到`springfox.swagger-ui`里面了。
要想访问这个页面需要配置下面的路径来处理。
```java
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/");
方法3搭配方法2
举个例子:
1. 将
/static
路径进行映射。1
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
2. 将参数中的文件名重新
forward
,这样也能实现根据参数提供静态文件名。1
2
3
4@GetMapping("file")
public void test(HttpServletRequest res, HttpServletResponse resp, String fileName) throws ServletException, IOException {
res.getServletContext().getRequestDispatcher("/static/"+fileName).forward(res, resp);
}