弹簧休息 - 发送文件列表时的异常
我正在尝试使用Spring Rest发送文件列表,但我得到了这个例外。
Could not write content: No serializer found for class java.io.ByteArrayInputStream
它适用于一个文件 ()。ByteArrayResource
它不适用于文件列表 ()。List<ByteArrayResource>
以下是我的代码的重要部分:
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);
我尝试了以下不起作用的方法:
- 发送数组而不是列表
- 将列表包装在 dto 中
- 发送字节[],但当文件>1.5Mb时它不起作用
我一直在调试反序列化,但理解起来非常痛苦!
如果可以提供帮助,则使用一个文件,使用转换器“”。ResourceHttpMessageConverter
有人有想法吗?
编辑:如果我在映射中逐个文件添加每个文件(而不是列表),则请求有效。
for (MultipartFile fichier : fichiers) {
map.add("files", new ByteArrayResource(fichier.getBytes()) {
@Override
public String getFilename()
{
return fichier.getOriginalFilename();
}
});
};
但我得到另一个例外:.目标服务器上启用了基本身份验证。如果我禁用它,一切都在工作!下面是目标服务器上的弹簧安全配置。org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/myApp/ws/file/save"
<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>
我在春季安全配置中是否遗漏了某些内容?
编辑2:标题中似乎没有令牌“授权”,手动添加它以解决问题
编辑3:问题解决了!将多个带有 spring rest 模板的文件发送到启用了基本身份验证的目标服务器时,需要(重新)添加基本身份验证令牌。这里有很好的解释:使用spring restTemplate的REST API的基本身份验证。我不知道这是否是一个错误(来自春天)。我在此更新之前的配置(我选择了拦截器方式)是这样的:
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);
我添加了这个:
this.restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(username, password));
该类是:
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);
}
}