利用Tomcat等中间件访问/下载大视频文件,启用文件缓存

背景

最近主要工作是开发文件服务相关接口,遇到很多性能问题,比如大文件读取内存溢出(java使用文件流上下传,防止内存溢出)、视频分片读取、浏览器图片缓存等问题。当时也想到一些解决方案,并完美解决。
后来发现,像Tomcat、Nginx这些应用服务器,对于这些问题,早已完美解决。

使用

项目是使用SpringBoot内置的Tomcat,用法如下:
使用外置静态资源目录作为文件下载服务,并开启文件缓存策略。

server:
  port: 80
  servlet:
    encoding:
      charset: UTF-8 # 设置UTF-8
      force: true #是否在HTTP请求和响应上强制编码到已配置的字符集。

spring:
  mvc:
    static-path-pattern: /contentfile/**
  resources:
  #   static-locations: classpath:/static
    static-locations: file:./files/contentfile
    cache:
      cachecontrol:
        max-age: 3600 #资源缓存时间,单位秒
    chain:
      compressed: true # 开启gzip压缩
      cache: true # 启用缓存
  servlet:
    multipart:
      # 设置单个文件大小
      max-file-size: 500MB
      # 设置单次请求文件的总大小
      max-request-size: 500MB

针对文件可重命名下载的需求,可使用过滤器设置下载文件名,如下:


public class UrlFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String requestQuery = httpRequest.getQueryString();
        String url = httpRequest.getServletPath().toLowerCase();
        url += (StringUtils.isEmpty(requestQuery) ? "" : "?" + requestQuery);
        System.out.println(url);

        // 获取url参数
        String downloadName = "";
        if (!StringUtils.isEmpty(requestQuery)) {
            var paramList = requestQuery.split("&");
            for (String item : paramList) {
                var query = item.split("=");
                if (query.length == 2) {
                    if (!StringUtils.isEmpty(query[0]) && "downloadname".equals(query[0].toLowerCase())) {
                        downloadName = URLDecoder.decode(query[1], "UTF-8");
                    }
                }
            }
        }

        // 判断是否需要重命名下载
        if (!StringUtils.isEmpty(downloadName)) {
            String userAgent = httpRequest.getHeader("User-Agent");
            userAgent = userAgent == null ? "" : userAgent.toLowerCase();
            // 针对IE或者以IE为内核的浏览器:
            if (userAgent.contains("msie") || userAgent.contains("trident")) {
                downloadName = URLEncoder.encode(downloadName, "UTF-8");
                downloadName = downloadName.replace("+", " ");
            } else {
                downloadName = new String(downloadName.getBytes(), "iso-8859-1");
            }
            httpResponse.setContentType("application/octet-stream; charset=UTF-8");
            HttpResponseUtils.writeHeader(httpResponse, "Content-Disposition",
                    "attachment;filename=\"" + downloadName + "\"");
        }

        filterChain.doFilter(request, response);
        return;
    }

    @Override
    public void destroy() {
    }
}

另外,外置静态资源目录还可以通过自定义静态资源映射配置类实现


@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {

    // 存放文档的根目录
    private static String rootPath = System.getProperty("user.dir");

    // 资源映射路径
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    	registry.addResourceHandler("/contentfile/**").addResourceLocations("file:./files/contentfile");
        //registry.addResourceHandler("/contentfile/**").addResourceLocations("file:" + rootPath + "/files/contentfile/");
        
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值