当前位置: 首页 > news >正文

企业级-实现Nginx的静态文件服务器映射

作者:fyupeng
技术专栏:☞ https://github.com/fyupeng
项目地址:☞ https://github.com/fyupeng/distributed-blog-system-api


留给读者

开发人员往往会经常需要通过浏览器下载文件、图片或者PDF或者缩略图等,这时候我们可以根据自己的需求自定义设置,安全性就可以由自己来把握。

一、介绍

难点主要在于把文件路径当成参数传给后端,后端根据一定的规则处理,将结果写入响应返回给浏览器。

优点

  • 使用懒加载方式,如果本地有,就不从OSS获取,本地没有先从OSS下载到本地,以便频繁下载文件时降低OSS的出入流量。
  • 待补充

二、代码

/*** @Auther: fyp* @Date: 2024/7/26* @Description: 文件预览处理器* @Package: com.gwssi.common.web* @Version: 1.0*/@Controller
public class FilePreviewController {//本地测试可改为自己的路径//private static final String FILE_DIRECTORY = "D:/upload/";private static final String FILE_DIRECTORY = "/data/hqzr/";@ResponseBody@RequestMapping(value = "/file/{fileUrl}/**",  method = RequestMethod.GET)public void getFile(@PathVariable String fileUrl, HttpServletRequest req, HttpServletResponse resp) throws IOException {String path = req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();String path2 = req.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();String args = new AntPathMatcher().extractPathWithinPattern(path2, path);args = args.replace(".do", "");fileUrl = fileUrl + "/" + args;File file = new File(FILE_DIRECTORY + fileUrl);byte[] bytes = null;// 添加安全检查,确保文件确实在预期的目录中if (!file.exists() || !file.isFile() || !file.getCanonicalPath().startsWith(new File(FILE_DIRECTORY).getCanonicalPath())) {// 处理非法访问,例如返回404File parentDir = file.getParentFile();if (!parentDir.exists()) {parentDir.mkdirs(); // 确保文件所在的目录存在}bytes = OssUtil.downloadByBytes(FILE_DIRECTORY + fileUrl);if (null != bytes) {FileOutputStream fos = new FileOutputStream(file);fos.write(bytes);fos.close();resp.reset(); // 非常重要} else {Map<String, String> map = new HashMap<String, String>();map.put("code", "-100");map.put("msg", "文件预览失败");ResponseUtil.returnFrontByJSON(map, resp);}}// 设置适当的响应头(纯下载方式)//resp.setContentType("application/octet-stream; charset=utf-8");//resp.setHeader("Content-Disposition", "attachment;filename=" + file.getName());// 直接预览打开resp.setContentType("image/png"); // 设置返回的文件类型resp.addHeader("Content-Length", String.valueOf(file.length()));  //文件大小// 使用ServletOutputStream将图片数据写入响应try (ServletOutputStream outputStream = resp.getOutputStream();BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {// 从文件服务器获取if (null != bytes) {outputStream.write(bytes);} else {// 从本地获取byte[] buffer = new byte[4096];int bytesRead = -1;// 读取文件内容并写入响应while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}// 刷新输出流,确保所有数据都被发送outputStream.flush();}}private String getMimeType(File file) {// 这里可以根据文件扩展名返回相应的MIME类型// 这里只是一个简单的示例,实际应用中可能需要更复杂的逻辑String filename = file.getName().toLowerCase();if (filename.endsWith(".png")) {return MediaType.IMAGE_PNG_VALUE;} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {return MediaType.IMAGE_JPEG_VALUE;}// 添加更多MIME类型判断...return MediaType.APPLICATION_OCTET_STREAM_VALUE; // 默认类型}
}

三、总结

简洁、高效、实用!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JVM(Java虚拟机) - JVM内存分配与内存管理
  • 发送邮箱调用接口时需要注意哪些安全事项?
  • [CP_AUTOSAR]_系统服务_DEM模块(一)功能及模块间依赖关系介绍
  • 数据结构初阶之排序(上)
  • 前端的学习-CSS(弹性布局-flex)
  • go语言day21 goland使用gin框架、gorm框架操作mysql数据库redis数据库 使用宝塔创建redis数据库
  • NIO专题学习(一)
  • 计算右侧小于当前元素的个数
  • 【C++】—— 类与对象(二)
  • [Git][认识Git]详细讲解
  • 【启明智显分享】适用于多功能养生壶、茶吧机的2.8寸触摸彩屏解决方案
  • uni-app封装组件实现下方滑动弹出模态框
  • NeRF学习——复现训练中的问题记录
  • 【全国大学生电子设计竞赛】2022年E题
  • TCP Analysis Flags 之 TCP Window Full
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 0x05 Python数据分析,Anaconda八斩刀
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • ES2017异步函数现已正式可用
  • JavaScript设计模式之工厂模式
  • JavaScript异步流程控制的前世今生
  • MySQL主从复制读写分离及奇怪的问题
  • Octave 入门
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • SQLServer之索引简介
  • vuex 学习笔记 01
  • webpack+react项目初体验——记录我的webpack环境配置
  • windows下如何用phpstorm同步测试服务器
  • 初探 Vue 生命周期和钩子函数
  • 关于字符编码你应该知道的事情
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 讲清楚之javascript作用域
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端临床手札——文件上传
  • 算法---两个栈实现一个队列
  • 学习HTTP相关知识笔记
  • 原生JS动态加载JS、CSS文件及代码脚本
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 从如何停掉 Promise 链说起
  • 选择阿里云数据库HBase版十大理由
  • ​queue --- 一个同步的队列类​
  • ​第20课 在Android Native开发中加入新的C++类
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (19)夹钳(用于送货)
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (二十六)Java 数据结构
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (未解决)macOS matplotlib 中文是方框
  • (一) 初入MySQL 【认识和部署】