下载文件时处理URL中出现特殊字符

概要

在URL中,有些字符具有特殊含义或可能引起歧义因此需要进行编码以确保在网络上传输时能正确解释。

例如:

  1. 空格:空格在URL中会被编码为 %20 或 +,因为在URL中空格是不允许的。

  2. 保留字符:某些字符在URL中具有特殊含义,如 &, =, ?, #, +, %等被称为保留字符。这些字符在某些情况下需要被编码,以免被误解为URL的组成部分。

  3. 非ASCII字符:非ASCII字符(如汉字、俄文等)需要进行编码,因为URL中只允许ASCII字符。

  4. 特殊符号:除了保留字符外,一些特殊符号像斜杠 /, 冒号 :, 问号 ?, 井号 #等都可能需要进行编码,以避免对URL的解析造成混淆。

  5. 控制字符和非打印字符:控制字符和非打印字符(如换行符、回车符等)在URL中不能直接出现,需要根据规范进行编码。

整体架构流程

 1.springboot
 2.spring-boot-starter-thymeleaf
 3.spring-boot-starter-web
 4.commons-io

技术名词解释

  1. springboot:Spring Boot 是一个用于快速构建基于 Spring 框架的应用程序的工具。
  2. spring-boot-starter-thymeleaf:Java模板引擎
  3. spring-boot-starter-web:快速构建基于 Spring MVC 的 Web 应用程序。
  4. commons-io : Apache Commons 工具库中的一个子项目,提供了许多操作输入输出的实用方法,以简化常见的 I/O 操作。

技术细节

controller代码

 @GetMapping("/download")
    public ResponseEntity<byte[]> fileDownload(String filename,HttpServletRequest request) throws Exception {
            
        String dirPath = "c:" + File.separator + "file" + File.separator;
        File file = new File(dirPath + File.separator + filename);
        //创建http头
        HttpHeaders headers = new HttpHeaders();
        //告诉浏览器要将收到的内容作为附件处理;filename 是要附加的文件名
        // 要让浏览器成功显示下载的文件名需要编码
        filename = getFilename(request, filename);
        headers.setContentDispositionFormData("attachment", filename);
        //设置内容类型为二进制流数据的类型
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        try {
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file),
                    headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<byte[]>(e.getMessage().getBytes(),
                    HttpStatus.EXPECTATION_FAILED);
        }
    }
 private String getFilename(HttpServletRequest request, String filename)
            throws Exception {
		//IE浏览器的关键词
        String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
        //获取用户代理信息/客户端信息
        String userAgent = request.getHeader("User-Agent");
        System.out.println("userAgent = " + userAgent);
        for (String keyWord : IEBrowserKeyWords) {
            if (userAgent.contains(keyWord)) {
            	// 如果包含这几个关键词将文件名重新进行编码成urf-8(文件名可能出现特殊字符)
                //字符串转换为一个以 UTF-8 编码的字节数组
                return URLEncoder.encode(filename, "UTF-8").replace("+"," ");
            }}
    //文件名重新编码成ISO_8859_1
        return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
    }

templates代码

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>文件下载</title></head>
<body>
<div style="margin-bottom: 10px">文件下载列表:</div>
<table>
    <tr>
        <td>bloglogo.jpg</td>
        <td><a th:href="@{/download(filename='bloglogo.jpg')}">下载文件</a></td>
    </tr>
    <tr>
        <td>春天机器人</td>
        <td><a th:href="@{/download(filename='Spring Boot')}">
            下载文件</a></td>
    </tr>
</table>
</body>
</html>

成功显示
在这里插入图片描述

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值