Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
671 views
in Technique[技术] by (71.8m points)

Java Spring Boot Download file with filename containing special characters produces zero byte downloaded file

JAVA_OPTS: -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
File System : Linux
Spring Boot : 2.1.4
Spring framework: 5.1.6.RELEASE
Library used : org.springframework.core.io.FileSystemResource;

The problem exists for example in German characters. For filename containing space %20 (encoded) works fine.

The problematic file is named Einzelh?ndler überprüfen.pdf and it's 12KB

Locally in windows and IntelliJ it works okay but in Linux it doesn't download .

final String relativePath = Paths.get(directory, UriUtils.decode(fileName, StandardCharsets.UTF_8)).toString();

 

final FileSystemResource res = new FileSystemResource(relativePath);
final String actualFileName = res.getFile().toPath().getFileName().toString();

 

final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDisposition(ContentDisposition.builder("attachment").filename(actualFileName).build());

 

return new ResponseEntity<>(res, headers, HttpStatus.OK);

final String actualFileName = res.getFile().toPath().getFileName().toString();

I have tried also this line with

final String actualFileName = UriUtils.encode(res.getFile().toPath().getFileName().toString(), StandardCharsets.UTF_8)).toString()

Does anybody know why this problem is happening ?

question from:https://stackoverflow.com/questions/65682390/java-spring-boot-download-file-with-filename-containing-special-characters-produ

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you have a problem with different file encodings. The best approach would be that you first analyze which OS your application running at and then work your way up to result like this.

 String input = new String(input_bytes, StandartCharsets.UTF_8); // on linux
 String input = new String(input_bytes, StandartCharsets.ISO_8859_1); // on windows

And create a helper class as follows:

  class OsUtils
{
   private static String OS = null;
   public static String getOsName()
   {
      if(OS == null) { OS = System.getProperty("os.name"); }
      return OS;
   }
   public static boolean isWindows()
   {
      return getOsName().startsWith("Windows");
   }

   public static boolean isUnix() {
       return getOsName().contains("nux");
   };// and so on
}

After, with some simple if check using the OsUtils classs, you can check which one to use. Hope it works!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...