java Resttemplate 表单/多部分:POST 中的图像 + JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29184215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resttemplate form/multipart: image + JSON in POST
提问by TamasGyorfi
I'm trying to call a rest ws (using resttemplate), that accepts an image and some JSON. However, I don't seem to be able to get it running.
我正在尝试调用一个rest ws(使用resttemplate),它接受一个图像和一些JSON。但是,我似乎无法让它运行。
The relevant code is as follows:
相关代码如下:
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
ByteArrayResource bytes = new ByteArrayResource(pictureData) {
@Override
public String getFilename() {
return pictureName;
}
};
map.add("x", x);
map.add("file", bytes);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity(map, header);
String response = restTemplate.postForObject(UPLOAD_URL, requestEntity, String.class);
Where x is some POJO with all the required JSON annotations (I receive it from another web service, that part works ok).
其中 x 是一些带有所有必需 JSON 注释的 POJO(我从另一个 Web 服务收到它,那部分工作正常)。
This thing, however, tells me: HttpMessageNotWritableException: Could not write request: no suitable HttpMessageConverter found for x.
但是,这件事告诉我:HttpMessageNotWritableException:无法写入请求:找不到适合 x 的 HttpMessageConverter。
If I change ByteArrayResource to byte[] then I get a 400 Bad Request. If I change the content type to JSON, then ByteArrayResource cannot be serialized into JSON:
如果我将 ByteArrayResource 更改为 byte[],则会收到 400 Bad Request。如果我将内容类型更改为 JSON,则 ByteArrayResource 无法序列化为 JSON:
Caused by: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.util.LinkedMultiValueMap["file"]->java.util.LinkedList[0]->a.b.c.["inputStream"]); nested exception is com.fasterxml.Hymanson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.util.LinkedMultiValueMap["file"]->java.util.LinkedList[0]->a.b.c.["inputStream"])
I have the following converters configured:
我配置了以下转换器:
StringHttpMessageConverter,
MappingHymanson2HttpMessageConverter
FormHttpMessageConverter
Any ideas, please? Thanks in advance.
有什么想法吗?提前致谢。
UPDATE
更新
So this is what I currently have after the instructions: I register the converters like this:
所以这就是我在指令之后目前所拥有的:我像这样注册转换器:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
restTemplate.getMessageConverters().add(new MappingHymanson2HttpMessageConverter());
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
formHttpMessageConverter.addPartConverter(new MappingHymanson2HttpMessageConverter());
formHttpMessageConverter.addPartConverter(new ResourceHttpMessageConverter()); // This is hope driven programming
restTemplate.getMessageConverters().add(new ResourceHttpMessageConverter());
restTemplate.getMessageConverters().add(formHttpMessageConverter);
Then in the ws call I have:
然后在 ws 电话中我有:
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON); //Also tried with multipart...
MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
ByteArrayResource bytes = new ByteArrayResource(pictureData) {
@Override
public String getFilename() {
return pictureName;
}
};
HttpHeaders xHeader = new HttpHeaders();
xHeader.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<X> xPart = new HttpEntity<>(x, xHeader);
multipartRequest.add("x", xPart);
HttpHeaders pictureHeader = new HttpHeaders();
pictureHeader.setContentType(MediaType.IMAGE_PNG);
HttpEntity<ByteArrayResource> picturePart = new HttpEntity<>(bytes, pictureHeader);
multipartRequest.add("file", picturePart);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity(multipartRequest, header);
return restTemplate.postForObject(UPLOAD_URL, requestEntity, String.class);
采纳答案by Sotirios Delimanolis
If you want to use ByteArrayResource
, simply register a ResourceHttpMessageConverter
.
如果您想使用ByteArrayResource
,只需注册一个ResourceHttpMessageConverter
.
If you want to use a byte[]
, simply register a ByteArrayHttpMessageConverter
.
如果您想使用byte[]
,只需注册一个ByteArrayHttpMessageConverter
。
The content type of the image part should be an image type, like image/png
, not application/json
.
图像部分的内容类型应该是图像类型,例如image/png
,而不是application/json
。
You can set each individual part's data type with
您可以设置每个单独部件的数据类型
HttpHeaders partHeaders = new HttpHeaders();
partHeaders.setContentType(MediaType.IMAGE_PNG);
HttpEntity<ByteArrayResource> bytesPart = new HttpEntity<ByteArrayResource>(bytes, partHeaders);
map.add("file", bytesPart);
Create your RestTemplate
by providing your collection of HttpMessageConverter
s
RestTemplate
通过提供您的HttpMessageConverter
s集合来创建您的
HttpMessageConverter<Object> Hymanson = new MappingHymanson2HttpMessageConverter();
HttpMessageConverter<Resource> resource = new ResourceHttpMessageConverter();
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
formHttpMessageConverter.addPartConverter(Hymanson);
formHttpMessageConverter.addPartConverter(resource); // This is hope driven programming
RestTemplate restTemplate = new RestTemplate(Arrays.asList(Hymanson, resource, formHttpMessageConverter));
and your outermost HttpEntity
should have a multipart content type
并且你最外面的HttpEntity
应该有一个多部分的内容类型
header.setContentType(MediaType.MULTIPART_FORM_DATA);