I'm trying to send a list of files with Spring Rest but I get this exception.
Could not write content: No serializer found for class java.io.ByteArrayInputStream
It works with one file (ByteArrayResource). 
It does not work with a list of files (List<ByteArrayResource>).
Here is the important parts of my code:
List<ByteArrayResource> contentsAsResource = new ArrayList<ByteArrayResource>();
for(MultipartFile fichier : fichiers) {
    contentsAsResource.add(new ByteArrayResource(fichier.getBytes()) {
        @Override
        public String getFilename()
        {
            return fichier.getOriginalFilename();
        }
    });
};
map.add("files", contentsAsResource);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(map, headers);
FormHttpMessageConverter formConverter = new FormHttpMessageConverter();
formConverter.setMultipartCharset(Charset.forName("UTF8"));
formConverter.addPartConverter(new MappingJackson2HttpMessageConverter());
this.restClientHelper.getRestTemplate().getMessageConverters().add(formConverter);
this.restClientHelper.getRestTemplate().postForObject("file/save", requestEntity, Object.class);
I've tried the following which did not work :
I've been debugging the deserialization but it's such a pain to understand!
If it can help, With one file, the converter 'ResourceHttpMessageConverter' is used.
Anyone have an idea?
EDIT: The request works if I add each file by file in the map (instead of a list).
for (MultipartFile fichier : fichiers) {
  map.add("files", new ByteArrayResource(fichier.getBytes()) {
    @Override
    public String getFilename()
    {
      return fichier.getOriginalFilename();
    }
  });
};
but I get another exception : org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/myApp/ws/file/save". There is a basic authentication enabled on the destination server. If i disabled it, everything is working! Here is the spring-security configuration on the destination server.
<http pattern="/ws/file/**" authentication-manager-ref="basicAuthenticationManager" create-session="stateless">
        <intercept-url pattern="/**" access="isAuthenticated()"/>
        <http-basic />
        <csrf disabled="true" />
        <headers disabled="true" />
</http>
Am I missing something in the spring security configuration ?
EDIT 2 : it seems there is not the token "Authorization" in the headers, adding it manually fix the problem
EDIT 3 : Problem solved! When sending multiples files with spring rest template to a destination server with basic auth enabled, it's needed to (re)add the basic authent token. It's well explained here : Basic authentication for REST API using spring restTemplate. I don't know if it's a bug or not (from Spring). My configuration before this update (I chose interceptor way) was this :
final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, motDePasse));
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
...
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClientBuilder.build());
this.restTemplate = new RestTemplate(requestFactory);
I've added this :
this.restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(username, password));
The class is :
 private static class BasicAuthorizationInterceptor implements ClientHttpRequestInterceptor
 {
   private final String username;
   private final String password;
   public BasicAuthorizationInterceptor(String username, String password)
   {
    this.username = username;
    this.password = (password == null ? "" : password);
   }
   @Override
   public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
   {
    byte[] token = Base64.getEncoder().encode((this.username + ":" + this.password).getBytes());
    request.getHeaders().add("Authorization", "Basic " + new String(token));
    return execution.execute(request, body);
   }
  }
                in the spring security configuration file is missing authentication provider . you can try this instead interceptor
<authentication-manager>
   <authentication-provider>
       <user-service>
       <user name="user" password="password"  />
       </user-service>
   </authentication-provider>
</authentication-manager>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With