ダウンロードされたファイルは元の中国語のファイル名を保持します。

必要

ファイルをダウンロードするときは、元の中国語のファイル名を維持する必要があります

成し遂げる

  • ファイル名:中文文件名.txt
  • URLEncoder.encode を使用した後のファイル名:%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D.txt
  • コード:
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)
}

原理

filename* は、Content-Disposition 応答ヘッダー フィールドの拡張子であり、HTTP 応答で Unicode ファイル名を指定するために使用され、RFC 5987 で指定されたファイル名を指定する方法をサポートし、UTF-8 でエンコードされた中国語文字をサポートします。 。対照的に、ファイル名フィールドは ASCII 文字のみをサポートするため、中国語のファイル名を直接指定することはできません。

HTTP/1.1 では、filename* フィールドの構文は次のように定義されます。

Content-Disposition: attachment; filename*=charset'lang'encoded-value

このうち、charset は指定されたエンコーディングの文字セット、lang は指定された言語の ISO 639-1 エンコーディング、encoded-value は指定されたファイル名のエンコードされた値です。RFC 5987 では、エンコードされた値を ASCII 文字セットのパーセント エンコードとしてエンコードし、ファイル名 * フィールドに埋め込むことが指定されています。

実際のアプリケーションでは、通常、UTF-8 エンコードと英語 (en) の言語エンコードを使用してファイル名を指定します。たとえば、次はファイル名* フィールドの例です。

Content-Disposition: attachment; filename*=UTF-8''%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D.txt

この例では、ファイル名は「中国語ファイル名.txt」、URL エンコードには UTF-8 エンコードが使用され、エンコード値は %E4%B8%AD%E6%96%87%E6%96%87% E4 です。 %BB%B6%E5%90%8D.txt はファイル名* フィールドに埋め込まれます。

filename* フィールドは Content-Disposition 応答ヘッダーの単なる拡張であるため、すべてのブラウザーとダウンロード ツールがこれをサポートしているわけではないことに注意してください。ブラウザまたはダウンロード ツールがファイル名* フィールドをサポートしていない場合は、ファイル名フィールドを使用してファイルを保存しようとします。この場合、互換性を確保するためにファイル名を URL エンコードする必要があります。

おすすめ

転載: blog.csdn.net/wwrzyy/article/details/131551562