SpringBoot映射URL访问本地文件,实现文件预览功能

文章目录

SpringBoot映射URL访问本地文件

基本实现

实现WebMvcConfigurer 接口,重写addResourceHandlers方法即可实现。

参考代码如下:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
 
    @Value("${accessFile.resourceHandler}")
    private String resourceHandler; 
 
    @Value("${accessFile.accessFilePath}")
    private String accessFilePath;

    /**
     * 配置静态资源映射
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 匹配到resourceHandler,将URL映射至accessFilePath(即本地文件夹)
        // registry.addResourceHandler("/files/**").addResourceLocations("file:E:/files/");
        registry.addResourceHandler(resourceHandler).addResourceLocations("file:///" + accessFilePath);
    }
}
 

举例:

resourceHandler 配置为/files/**,accessFilePath配置为E:/files/。

那么页面请求 ip:端口/context-path/files/需要访问的文件 ,即可访问到本地磁盘E:/files/下面的同名文件。
特别注意:

  • accessFilePath必须以"/"结尾,否则映射不到。

中文资源名称无法访问,英文名正常

解决办法一:重写configurePathMatch方法,UrlPathHelper设置不decodeurl

java 复制代码
  @Override
  public void configurePathMatch(PathMatchConfigurer configurer) {
      UrlPathHelper urlPathHelper=new UrlPathHelper();
      urlPathHelper.setUrlDecode(false);
      urlPathHelper.setDefaultEncoding(StandardCharsets.UTF_8.name());
      configurer.setUrlPathHelper(urlPathHelper);
  }

解决办法二:增加配置文件

yaml 复制代码
spring:
  mvc:
    pathmatch:
      matching-strategy: ant-path-matcher

这个方案适用于SpringBoot 2.6.+,而公司项目用的版本是2.7.+,使用上面的方法并没有生效。

文件预览-解决方案

由于访问服务器文件的方式不安全,且现在中文文件访问报错解决不了,最终重新写了一个文件下载接口,前端根据返回的文件流进行预览展示。
参考代码如下:

java 复制代码
@Operation(summary = "在线预览pdf")
@GetMapping("/onlinePreview")
public void onlinePreview(@Valid @NotEmpty(message = "id不能为空") String id, HttpServletResponse response) {
    jxOrgFileRecordService.onlinePreview(id,response);
}
java 复制代码
@Override
public void onlinePreview(String id, HttpServletResponse response) {
    // 1、查询数据是否存在
    JxOrgFileRecordEntity dbFileRecordVo = jxOrgFileRecordMapper.selectById(id);
    if(dbFileRecordVo == null){
        throw new BusinessException("未查询到报告记录数据。");
    }
    // 2、拼接服务器文件全路径:wordPath+year+pdfName
    String pdfName = dbFileRecordVo.getPdfPath().substring(dbFileRecordVo.getPdfPath().lastIndexOf("/")+1);
    String fullPath = wordPath+File.separator+year+File.separator+pdfName;
    // 3、服务器文件是否存在
    File file = new File(fullPath);
    if (!file.exists()) {
        log.error("onlinePreview 文件全路径:{}",fullPath);
        throw new BusinessException("文件:{}不存在。",pdfName);
    }
    // 4、返回文件流
    // 直接在try()中创建流对象 会默认关闭
    try( FileInputStream input = new FileInputStream(file)) {
        byte[] data = new byte[input.available()];
        while (input.read(data) > 0) {
        }
        response.getOutputStream().write(data);
    } catch(Exception ex) {
       log.error("onlinePreview pdf文件处理异常:",ex);
    }
}
相关推荐
Penge6666 小时前
Go 接口编译期断言
后端
我是一颗柠檬6 小时前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试
橙淮7 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿7 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影7 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
Ceelog7 小时前
久坐党自救指南:屏幕前 8 小时,身体到底在经历什么
前端·后端
EntyIU8 小时前
JVM内存与GC笔记
java·jvm·笔记
XS0301068 小时前
并发编程 六
java·后端
yaoxin5211238 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道8 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试