如何以西里尔文返回下载的文件名? [英] How to return downloaded file name in Cyrillic?

查看:162
本文介绍了如何以西里尔文返回下载的文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想返回西里尔字母的文件。

I want to return file with Cyrillic name.

现在我的代码如下:

@GetMapping("/download/{fileId}")
    public void download(@PathVariable Long fileId, HttpServletResponse response) throws IOException {
        ...
        response.setContentType("txt/plain" + "; charset=" + "WINDOWS-1251");
        String filename = "русское_слово.txt";
        response.addHeader("Content-disposition", "attachment; filename=" + filename);
        response.addHeader("Access-Control-Expose-Headers", "Content-disposition");
        //...
    }

当我从浏览器访问url时-浏览器为我提供了一个对话框,用于将文件保存到磁盘上,但显示 _ 而不是西里尔符号。

When I access url from browser - browser provides me dialog to save file on disk but it show _ instead of Cyrillic symbols.

看起来像是响应标头编码问题:

Looks like it is response header encoding issue:

{
  "access-control-expose-headers": "Content-disposition",
  "content-disposition": "attachment; filename=???_??.txt",
  "date": "Fri, 28 Dec 2018 15:53:44 GMT",
  "transfer-encoding": "chunked",
  "content-type": "txt/plain;charset=WINDOWS-1251"
}

我尝试了以下选项:

response.addHeader("Content-disposition", "attachment; filename*=UTF-8''" + filename);

及以下内容:

response.addHeader("Content-disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(filename,"UTF-8"));

但没有帮助

如何解决此问题?

推荐答案

如果您使用的是Spring 5+,则可以使用 ContentDisposition

If you're on Spring 5+ you can use ContentDisposition:

String filename = "русское слово.txt";

ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
    .filename(filename, StandardCharsets.UTF_8)
    .build();
System.out.println(contentDisposition.toString());

输出:

attachment; filename*=UTF-8''%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%BE%D0%B5%20%D1%81%D0%BB%D0%BE%D0%B2%D0%BE.txt

ContentDisposition 隐藏了您要尝试执行的所有工作(请参见其 toString 实现):

The ContentDisposition hides all the work you're trying to do (see its toString implementation):

if (this.filename != null) {
    if (this.charset == null || StandardCharsets.US_ASCII.equals(this.charset)) {
        sb.append("; filename=\"");
        sb.append(this.filename).append('\"');
    }
    else {
        sb.append("; filename*=");
        sb.append(encodeHeaderFieldParam(this.filename, this.charset));
    }
}






另外,如果您不想直接处理 HttpServletRequest ,则可以返回 ResponseEntity 代替:


Also if you don't want to deal with HttpServletRequest directly you can return ResponseEntity instead:

@RequestMapping("/")
public ResponseEntity<Resource> download() {
  HttpHeaders httpHeaders = new HttpHeaders();
  String filename = "русское_слово.txt";

  ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
      .filename(filename, StandardCharsets.UTF_8)
      .build();
  httpHeaders.setContentDisposition(contentDisposition);

  return new ResponseEntity<>(new ByteArrayResource(new byte[0]),
      httpHeaders, HttpStatus.OK);
}

这篇关于如何以西里尔文返回下载的文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆