2017-02-13 9 views
1

Я пытаюсь опубликовать список MultipartFile для моего RestController с помощью Spring RestTemplate, хотя я немного смущен в отношении точного синтаксиса & типов, используемых для мой клиент & контроллер. Вот то, что я до сих пор основаны на исследованиях, я сделал ...Загрузка списка MultipartFile с помощью Spring 4 restTemplate (Java Client & RestController)

FileUploadClient.java

public void uploadFiles(List<MultipartFile> multiPartFileList) throws IOException { 
    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); 
    List<Object> files = new ArrayList<>(); 
    for(MultipartFile file : multiPartFileList) { 
     files.add(new ByteArrayResource(file.getBytes())); 
    } 
    map.put("files", files); 

    // headers is inherited from BaseClient 
    headers.setContentType(MediaType.MULTIPART_FORM_DATA); 
    HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers); 
    ResponseEntity<String> response = restTemplate.exchange(restURI + "/rest/fileupload/uploadfiles", HttpMethod.POST, request, String.class); 
    if(HttpStatus.OK.equals(response.getStatusCode())) { 
     System.out.println("status for /rest/fileupload/uploadfiles ---> " + response); 
    } 
} 

FileUploadRestController.java

@RequestMapping(value = "/uploadfiles", method = RequestMethod.POST) 
public ResponseEntity<?> uploadFiles(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) { 
    ResponseEntity<?> response; 
    try { 
     // do stuff... 
     response = new ResponseEntity<>(header, HttpStatus.OK); 
     System.out.println("file uploaded"); 
    } catch (Exception e) { 
     // handle exception 
    } 
    return response; 
} 

web.xml

<filter> 
    <filter-name>multipartFilter</filter-name> 
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>multipartFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

весна-servlet.xml

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
    <!-- max upload size in bytes --> 
    <property name="maxUploadSize" value="20971520" /> <!-- 20MB --> 
    <!-- max size of file in memory (in bytes) --> 
    <property name="maxInMemorySize" value="1048576" /> <!-- 1MB --> 
</bean> 

Если я правильно понимаю. Мультипартийный фильтр должен анализировать мой MultiValueMap в список файлов MultipartFile и MultipartHttpServletRequest? Единственный способ, которым я могу заставить моего клиента ударить мой RestController, - отправить данные файла как ByteArrayResource, однако в моем контроллере моя RequestBody всегда равна null, а MultipartHttpServletRequest имеет пустую карту для своего атрибута multipartFiles. Я просмотрел многочисленные сообщения, чтобы попытаться решить эту проблему, но безрезультатно. Любая помощь приветствуется.

ответ

4

Похоже, что полезная нагрузка request, которую вы отправляете с FileUploadClient, не соответствует ожидаемому серверу. Не могли бы вы попробовать изменить следующее:

MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); 
for(MultipartFile file : multiPartFileList) { 
    map.add(file.getName(), new ByteArrayResource(file.getBytes())); 
} 

в

MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); 
List<ByteArrayResource> files = new ArrayList<>(); 
for(MultipartFile file : multiPartFileList) { 
    files.add(new ByteArrayResource(file.getBytes())); 
} 
map.put("files", files); 

Кроме того, вы могли бы попробовать изменить метод подписи сервера на следующее:

public ResponseEntity<?> uploadFiles(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) { 

Update

При загрузке нескольких файлов вам необходимо чтобы убедиться, что getFileName из ByteArrayResource возвращает одинаковое значение каждый раз. Если нет, вы всегда получите пустой массив.

E.g. не следующие работы для меня:

Клиент:

MultiValueMap<String, Object> data = new LinkedMultiValueMap<String, Object>(); 
for(MultipartFile file : multiPartFileList) { 
    ByteArrayResource resource = new ByteArrayResource(file.getBytes()) { 
     @Override 
     public String getFilename() { 
      return ""; 
     } 
    }; 
    data.add("files", resource); 
} 

Сервер

public ResponseEntity<?> upload(@RequestParam("files") MultipartFile[] files){ 
+0

Когда я сделал эти изменения, мой контроллер остальное уже не получить удар. Когда я перешел на «Список files = new ArrayList <>();' в Client & '@RequestParam (« files ») Список файлов в контроллере, затем он снова попадает, а файлы заполняются арраистом строк, m - байты для файла. – Steve

+0

Я также должен отметить эту карту.put («файлы», файлы); дал мне это предупреждение: 'Метод put (String, List ) в типе Map > не применим для аргументов (String, List )', поэтому мне пришлось использовать 'map.add («файлы», файлы); «Когда я изменил объект, пусть я использую put. – Steve

+0

Да, все в порядке. Можете ли вы попробовать изменить «Список ' '' List '? –

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