业务场景:
系统上有个磁盘,里面存放了很多文件,有没有什么办法,可以通过 http 请求,快速访问这些文件,最好写一两行代码就能实现。
Tomcat配置
修改 server.xml 配置。
缺点显而易见,但凡知道地址,就可以下载文件,只要愿意,甚至把一整个服务器的文件载下来,因为独立于系统之外,系统内部代码很难限制文件的访问。
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context path="/rgyx_files" docBase="C:/xxxxx" reloadable="true" crossContext="true"></Context>
</Host>
Nginx
tomcat 与 nginx 某些角度来说,算是对标产品了,tomcat 有的功能 nginx 一般也会有,
因为暂未参与过相关配置,这里提供一下思路,你们自己百度了。
Spring配置方式
这个配置的一般用途是,用于映射 WEB-INF 下的资源文件。其实,mvc:resources 也可以将路径映射到项目外的磁盘目录。
<mvc:resources mapping="/${mapping_path}/**" location="file:${local_path}/">
<!-- 系统主题 -->
<mvc:resources location="/WEB-INF/static/theme/" mapping="/theme/**" />
<mvc:resources location="/WEB-INF/static/js/" mapping="/js/**" />
<!-- 通用JS -->
<mvc:resources location="/WEB-INF/static/lib/" mapping="/lib/**" />
<!-- 通用资源 -->
<mvc:resources location="/WEB-INF/static/res/" mapping="/res/**" />
<!-- LTE 风格管理页面 -->
<mvc:resources location="/WEB-INF/static/pages/" mapping="/pages/**" />
SpringBoot的配置方式
等价于上述的 Spring 的配置,缺点就是:如果访问的是文件夹,你可能是希望它能返回文件夹的文件列表;对于共享文件,会出现文件无法读取的现象。
/**
* 代码样例
* @param registry -
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/seaboot/file/**").addResourceLocations("file:xxxxxxx");
logger.debug("开放文件上传资源目录:" + uploadConstant.getRoot());
}
源代码实现
因为是自己编码实现的,因此,要实现什么样的逻辑,都是可以的。将Url映射到我们的服务器磁盘,然后通过response写入文件即可。
cn.seaboot.common.core的相关代码,一般能在 apache-commons 中找到替代的写法。
如果你非常熟悉下载文件的相关代码,那么就能轻易读懂下面的代码,基本思路,就是从 url 中截取文件信息,然后将文件下载下来。
import cn.seaboot.common.core.CommonUtils;
import cn.seaboot.common.core.FastJsonUtils;
import cn.seaboot.common.file.MimeUtils;
import cn.seaboot.common.file.ResponseWriter;
import cn.seaboot.web.jackson.Result;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
/**
* 资源映射
*
* @author Mr.css
* @date 2020-09-30 20:01:38
*/
@Controller
@RequestMapping(value = "/sys/resource")
public class ResourceController {
/**
* 资源映射
*/
private Map<String, String> pathMapping = new HashMap<>();
@PostConstruct
public void init() {
pathMapping.put("image", "C:/Users/postm/Desktop");
}
@RequestMapping(value = "**", method = RequestMethod.GET)
public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
if (!pathMapping.isEmpty()) {
//start - Url路径截取,只是为了,从Url中获取文件的存储路径(按照自己的想法实现)
String servletPath = request.getServletPath();
String mappingPath = servletPath.substring(14);
int idx = mappingPath.indexOf('/');
if (idx < 0) {
idx = mappingPath.length();
}
String key= mappingPath.substring(0, idx);
String path = pathMapping.get(key);
String value = mappingPath.substring(idx);
//end --
File file = new File(path + value);
if (file.exists()) {
if (file.isFile()) {
//如果是文件,则提供文件的预览功能
ResponseWriter.create(request, response)
.setPreviewName(file.getName())
.write(new FileInputStream(file));
} else {
//如果是文件夹,则列出文件夹下的全部文件,写成JSON数据
List<Map<String, Object>> list = genFileList(file);
Result result = Result.succeed(list);
String json = FastJsonUtils.toJSONString(result);
ResponseWriter.create(request, response)
.setContentType(MimeUtils.MIME_JSON)
.write(json);
}
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
}
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
private List<Map<String, Object>> genFileList(File directory) {
File[] files = directory.listFiles();
if (CommonUtils.isEmpty(files)) {
return Collections.emptyList();
} else {
List<Map<String, Object>> list = new ArrayList<>(files.length);
for (File file : files) {
Map<String, Object> map = new HashMap<>();
map.put("name", file.getName());
map.put("length", file.length());
map.put("lastModified", file.lastModified());
map.put("canRead", file.canRead());
map.put("canWrite", file.canWrite());
list.add(map);
}
return list;
}
}
}
效果如下:
通过http请求,就可以获取电脑桌面的全部文件信息。