need
When downloading files, you need to keep the original Chinese file name
accomplish
- file name:
中文文件名.txt
- Filename after using URLEncoder.encode:
%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D.txt
- Code:
fun downloadFile(
bytes: ByteArray,
fileName: String,
mediaType: String = MediaTypes.APPLICATION_BINARY,
) {
val response = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes).response!!
response.contentType = mediaType
// 先将文件名编码
val encodeFileName = URLEncoder.encode(fileName, "UTF-8")
// 再传入响应头中,主要是:fileName*=UTF-8''$encodeFileName,接下来的事情交给浏览器
// UTF-8 指定你使用的编码方式,encodeFileName为你编码后的文件名
response.setHeader(
FileUploadBase.CONTENT_DISPOSITION, "attachment;fileName*=UTF-8''$encodeFileName"
)
response.outputStream.write(bytes)
}
principle
filename* is an extension of the Content-Disposition response header field, which is used to specify a Unicode file name in the HTTP response, and supports the method specified in RFC 5987 to specify the file name, and supports UTF-8 encoded Chinese characters. In contrast, the filename field only supports ASCII characters, so Chinese filenames cannot be directly specified in it.
In HTTP/1.1, the syntax of the filename* field is defined as follows:
Content-Disposition: attachment; filename*=charset'lang'encoded-value
Among them, charset is the character set of the specified encoding, lang is the ISO 639-1 encoding of the specified language, and encoded-value is the encoded value of the specified file name. RFC 5987 specifies encoding an encoded-value as a percent-encode of the ASCII character set, which is then embedded in a filename* field.
In practical applications, usually use UTF-8 encoding and language encoding as English (en) to specify the file name. For example, the following is an example of a filename* field:
Content-Disposition: attachment; filename*=UTF-8''%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D.txt
In this example, the file name is "Chinese file name.txt", UTF-8 encoding is used for URL encoding, and the encoded value %E4%B8%AD%E6%96%87%E6%96%87% E4%BB%B6%E5%90%8D.txt is embedded in the filename* field.
It should be noted that the filename* field is just an extension of the Content-Disposition response header, so not all browsers and download tools support it. If the browser or download tool does not support the filename* field, it will try to use the filename field to save the file. In this case, the filename needs to be URL-encoded to ensure compatibility.