2016-11-25 20 views
11

Tôi đang cố gắng gửi danh sách tệp có Spring Rest nhưng tôi nhận được ngoại lệ này.Nghỉ ngơi mùa xuân - Ngoại lệ khi gửi Danh sách tệp

Could not write content: No serializer found for class java.io.ByteArrayInputStream

Nó hoạt động với một tập tin (ByteArrayResource).

Nó không hoạt động với danh sách tệp (List<ByteArrayResource>).

Dưới đây là những phần quan trọng của mã của tôi:

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); 

Tôi đã thử những điều sau đây mà không làm việc:

  • gửi một mảng thay vì một danh sách
  • quấn danh sách trong một dto
  • gửi byte [] nhưng nó không hoạt động khi tệp> 1.5Mb

Tôi đã gỡ lỗi deserialization nhưng nó là một nỗi đau để hiểu!

Nếu có thể trợ giúp, Với một tệp, công cụ chuyển đổi 'ResourceHttpMessageConverter' được sử dụng.

Có ai có ý tưởng không?

EDIT: Yêu cầu hoạt động nếu tôi thêm từng tệp theo tệp trong bản đồ (thay vì danh sách).

for (MultipartFile fichier : fichiers) { 
    map.add("files", new ByteArrayResource(fichier.getBytes()) { 
    @Override 
    public String getFilename() 
    { 
     return fichier.getOriginalFilename(); 
    } 
    }); 
}; 

nhưng tôi có ngoại lệ khác: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/myApp/ws/file/save". Có một xác thực cơ bản được kích hoạt trên máy chủ đích. Nếu tôi vô hiệu hóa nó, mọi thứ đều hoạt động! Đây là cấu hình bảo mật mùa xuân trên máy chủ đích.

<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> 

Tôi có thiếu thứ gì đó trong cấu hình bảo mật mùa xuân không?

EDIT 2: có vẻ như không có token "Authorization" trong tiêu đề, thêm nó bằng tay sửa chữa vấn đề

EDIT 3: Giải quyết vấn đề! Khi gửi các tệp bội số với mẫu khôi phục mùa xuân đến máy chủ đích có bật auth cơ bản, cần phải (lại) thêm mã thông báo xác thực cơ bản. Nó cũng được giải thích ở đây: Basic authentication for REST API using spring restTemplate. Tôi không biết đó có phải là lỗi hay không (từ mùa xuân). cấu hình của tôi trước khi bản cập nhật này (tôi đã chọn chặn chiều) được điều này:

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); 

Tôi đã thêm này:

this.restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(username, password)); 

Lớp là:

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); 
    } 

    } 
+0

[Tham khảo] (http: // stackoverflow.com/questions/25103070/resttemplate-httpmessagenotwritableexception-no-serializer-found-for-class-ja) – Onkar

+0

Cảm ơn. Tôi đã nhìn thấy bài đăng này. Mã của tôi khá giống nhau. – Clemzd

+0

để câu hỏi của bạn không còn về Mẫu Nghỉ ngơi Mùa xuân mà còn về bảo mật mùa xuân? Nếu bạn muốn hỗ trợ bảo mật trên máy chủ đích, yêu cầu của bạn sẽ được xác thực (đặt tiêu đề cũ: 'Cấp phép: Cơ bản QWxhZGRpbjpPcGVuU2VzYW1l' –

Trả lời

0

trong cấu hình bảo mật mùa xuân tệp thiếu nhà cung cấp xác thực. bạn có thể thử thiết bị này thay vì máy đánh chặn

<authentication-manager> 
    <authentication-provider> 
     <user-service> 
     <user name="user" password="password" /> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 
Các vấn đề liên quan