文件服务器的搭建架构有很多种,如基于nginx+vsftp、nginx+fastDFS等架构,其中vsftp或fastDFS用于文件读写、上传存储、下载,nginx用于映射文件 ,方便http访问静态文件,实现在线预览图片或下载等功能。这种架构使用起来很方便,而且fastDFS支持集群、主从备份等,因而很采公司或开发人员的青睐,但这种构架是无法满足某些场景的需求,如增加文件访问权限校验、时效等,仅凭nginx无法做到,一般可能需要结合luna针对nginx开发模块,而采用Java、Spring则可以很方便实现这个功能。Spring对于静态文件访问有着较好的支持,并支持多种文件映射,如本地文件、jar、ftp等文件类型,Spring框架本身可解析大部分文件类型。
文件服务器的基本原理就是将文件以流或字节输出到客户端。
Spring静态文件配置
相信熟悉tomcat的同学都知道tomcat可作为静态文件服务器,将文件放入webapps目录下,即可用host+path来访问或下载文件。
SpringMVC框架也支持对于静态文件mapping的方式来实现文件服务器功能,配置有如下两种。
1.xml配置
在主springmvc主配置文件中添加
<mvc:annotation-driven />
<mvc:resources mapping="/images/**" location="/images/" />
/images/**映射到 ResourceHttpRequestHandler进行处理,location指定静态资源的位置.可以是web application根目录下、jar包里面,这样可以把静态资源压缩到jar包中。这样当访问http://host/images/{file_path}
时,则会到/images/
目录下去找相应的文件。
location配置支持系统文件、ftp文件、jar文件,对应的配置为file://
、ftp://
、jar://
,支持Http网络, DFS协议地址, VFS协议地址,jar包,可参考File、FTP等协议说明。
2.springboot配置
public class FileServerConfig extends WebMvcConfigurerAdapter{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**").addResourceLocations("file://");
}
}
以上配置则可实现对于系统文件的访问,相当于一个小的文件服务器,采用springmvc做为http访问入口、本地文件系统或ftp文件系统做为文件仓库。
Spring Resources访问原理
以上是利用spring做文件服务器的使用配置,那么spring是如何做到这一点的?
其实在配置resources时,当访问url时,spring 分发交给对应的mappingHandler去处理,而静态文件则由ResourceHttpRequestHandler.handleRequest处理。主要过程是查找资源、解析资源类型、设置content-type,response输出流。
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取资源文件,Resource是spring对静态资源的高度封装,可以看成是文件流或字节
Resource resource = this.getResource(request);
if(resource == null) {
logger.trace("No matching resource found - returning 404");
response.sendError(404);
} else if(HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader("Allow", this.getAllowHeader());
} else {
//2.判断Http请求头,是否有断点续传、解析文件类型设置http返回流ContentType
this.checkRequest(request);
if((new ServletWebRequest(request, response)