2

У меня есть служба загрузки Spring Spring, которая загружает файл через метод обмена RestTemplate. Загрузка работает так, как должна, но есть проблема с именами файлов utf-8, которые, например, содержат немецкие умлауты, такие как äöü. При загрузке файла из приложения HTML5 он работает без каких-либо проблем, поэтому это не проблема в принимающей службе.Spring Boot (1.2.5.RELEASE) Resttemplate Multipart File Upload UTF-8 Имя файла невозможно

Без настройки какой-либо кодировки для MultipartCharset умляуты заменяются на «?» (например, Überschrift.txt получает? berschrift.txt), поскольку US-ASCII используется для кодирования имени файла. Я попытался установить MultipartCharset в UTF-8 с помощью этого кода:

((AllEncompassingFormHttpMessageConverter)restTemplate.getMessageConverters().get(4)).setMultipartCharset(Charset.forName("UTF-8")); 

Затем имя файла помещается как это в запросе: Content-Disposition: форм-данных; Name = "файл"; filename = "=? UTF-8? Q? = C3 = 9Cberschrift.txt? ="

Умлауты закодированы, но имя файла передается точно так же, как это, а не с правильными умлаутами. Я думаю, что мне не хватает какого-либо свойства для установки, поэтому умляуты действительно заданы как умляуты в запросе.

Соответствующая часть моего кода заключается в следующем:

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(uploadFile),"UTF-8")); bw.append(capturedDocument.getText()); 
bw.newLine(); 
bw.flush(); 
bw.close(); 

String complianceServiceUrl = complianceBackendRestSettings.getComplianceServiceURL(); 
      RestTemplate restTemplate = new RestTemplate(); 
      ((AllEncompassingFormHttpMessageConverter)restTemplate.getMessageConverters().get(4)).setMultipartCharset(Charset.forName("UTF-8")); 
ResponseEntity<JSONBoolean> responseEntity = null; 
HttpHeaders uploadHeaders = new HttpHeaders(); 
uploadHeaders.set("Authorization", authorization); 
uploadHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); 
LinkedMultiValueMap<String, Object> uploadMap = new LinkedMultiValueMap<String, Object>(); 
uploadMap.add("file", new FileSystemResource(uploadFile.getAbsolutePath())); 
uploadMap.add("abonnementId", abos.toString()); 
       HttpEntity<LinkedMultiValueMap<String, Object>> uploadRequestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
         uploadMap, uploadHeaders); 
responseEntity = restTemplate.exchange(complianceServiceUrl + "/uploadandassign", HttpMethod.POST, 
uploadRequestEntity, JSONBoolean.class); 

В умляутах в файлах завершен правильно, так что это только проблема с кодировкой имен файлов.

Я был бы признателен за любые рекомендации по решению этой проблемы.

ответ

0

У меня возникла такая же проблема, но установка множительной карты для нее была исправлена. Код клиента выглядит правильно, и имя файла правильно закодировано в формате RFC 2047. Эта кодировка необходима, потому что HTTP только принимает ascii в своих заголовках. (What character encoding should I use for a HTTP header?)

На сервере он затем должен быть декодирован обратно на страницу Überschrift.txt. Я не совсем уверен, какая рессора делает это (предполагая, что ваш серверное также написано весной), но я предполагаю, что это многочастный распознаватель

2

Я также столкнулся с аналогичной проблемой, проблема заключается в том, что в Spring RestTemplate следует RFC 2047, но StandardMultipartHttpServletRequest поддерживает только формат RFC 6266 или заголовки должны быть уже в UTF-8 (что такое поведение некоторых браузеров).

Я уже заполнил bug request. Я только что проверил, что библиотека commons-fileupload будет обрабатывать это правильно. Если вы используете Spring бутс, вам потребуется:

  1. Добавить Викисклад FileUpload 1.3.2 на пути к классам

    <dependency> 
        <groupId>commons-fileupload</groupId> 
        <artifactId>commons-fileupload</artifactId> 
        <version>1.3.2</version> 
    </dependency> 
    
  2. Отключить MultipartAutoConfiguration - например, собственностью spring.http.multipart.enabled=false или по @EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})

  3. Определите MultipartResolver в вашем классе конфигурации

    @Bean 
    public MultipartResolver multipartResolver() { 
        return new CommonsMultipartResolver(); 
    } 
    
+0

Спасибо тонну @myroch за четкое и понятное объяснение и решение. –

Смежные вопросы