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

SpringBoot映射URL访问本地文件

基本实现

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

参考代码如下:

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

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

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

spring:
  mvc:
    pathmatch:
      matching-strategy: ant-path-matcher

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

文件预览-解决方案

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

@Operation(summary = "在线预览pdf")
@GetMapping("/onlinePreview")
public void onlinePreview(@Valid @NotEmpty(message = "id不能为空") String id, HttpServletResponse response) {
    jxOrgFileRecordService.onlinePreview(id,response);
}
@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);
    }
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-27 15:40:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-27 15:40:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-27 15:40:03       87 阅读
  4. Python语言-面向对象

    2024-04-27 15:40:03       96 阅读

热门阅读

  1. 《设计模式之美》第五章 总结

    2024-04-27 15:40:03       37 阅读
  2. 动手学深度学习——pandas

    2024-04-27 15:40:03       29 阅读
  3. c++11 call_once 和 once_flag

    2024-04-27 15:40:03       26 阅读
  4. vue项目,普通js文件添加全局变量

    2024-04-27 15:40:03       28 阅读
  5. STM32 ULINK

    2024-04-27 15:40:03       31 阅读
  6. 2023年第13届山东省大学生程序设计竞赛题解

    2024-04-27 15:40:03       28 阅读
  7. Linux中的时间戳mtime,ctime,ctime

    2024-04-27 15:40:03       30 阅读
  8. 等保测评试题分享(7)

    2024-04-27 15:40:03       37 阅读
  9. TS泛型类型

    2024-04-27 15:40:03       36 阅读
  10. MySQL 数据表

    2024-04-27 15:40:03       30 阅读