如何使用RestTemplate发布Atom条目和文件



我正在尝试使用RestTemplate发布Atom xml和带有多部分/相关请求的文件。问题是,是否可以更改部分的标题,例如原子部分中边界后显示的内容类型,或在文件部分中添加内容ID,或者在这种情况下如何正确创建发布请求。我的请求应该是这样的:

POST /app/psw HTTP/1.1 
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2 
Host: localhost 
Accept: */* 
Authorization: Basic YWdzOmFnczEyMw== 
Content-Type: multipart/related;boundary===9B752C681081408==;type=application/atom+xml 
Content-Length: 7019 
Expect: 100-continue 
--==9B752C681081408== 
Content-Type: application/atom+xml 
<?xml version="1.0" encoding="utf-8"?>
<atom:entry ...>
...
</atom:entry>
--==9B752C681081408== 
Content-Type: video/mp2t 
Content-ID: <prod@example.com>
123f3242e34...binary data...12313ed
--==9B752C681081408==--

我必须使用RestTemplate或Spring WebClient。

目前,它看起来如下所示,但带有atom的部分具有内容类型:application/xml,而不是application/atom+xml

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().stream()
.filter(FormHttpMessageConverter.class::isInstance)
.map(FormHttpMessageConverter.class::cast)
.findFirst()
.ifPresent(formHttpMessageConverter -> {
List<MediaType> supportedMediaTypes = new ArrayList<>(formHttpMessageConverter.getSupportedMediaTypes());
supportedMediaTypes.add(new MediaType("multipart","related"));
formHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
});
ResponseEntity<String> response;
LinkedMultiValueMap<String,Object> map = new LinkedMultiValueMap<>();

map.add("atom",e); //e is xml object created with javax.xml.bind package
map.add("file",new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","multipart/related;type="application/atom+xml"");
HttpEntity<LinkedMultiValueMap<String,Object>> request = new HttpEntity<>(map,headers);
response = restTemplate.postForEntity(url,request,String.class);

提前感谢

好的,我找到了适合我的解决方案。我会一步一步地解释我是如何做到的。

  1. 准备RestTemplate
private RestTemplate prepareRestTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
RestTemplate template = new RestTemplate(requestFactory);
template.getMessageConverters().stream()
.filter(FormHttpMessageConverter.class::isInstance)
.map(FormHttpMessageConverter.class::cast)
.findFirst()
.ifPresent(formHttpMessageConverter -> {
List<MediaType> supportedMediaTypes = new ArrayList<>(formHttpMessageConverter.getSupportedMediaTypes());
supportedMediaTypes.add(new MediaType("multipart", "related"));
formHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
});
return template;
}
  1. 创建标头
private HttpHeaders createHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/related;type="application/atom+xml"");
headers.setBasicAuth(properties.getProperty("service.login"), properties.getProperty("service.password"));
return headers;
}
  1. 创建atom xml部分
private HttpEntity<String> createAtomPart(String xml) {
MultiValueMap<String, String> atomMap = new LinkedMultiValueMap<>();
atomMap.add(HttpHeaders.CONTENT_TYPE, "application/atom+xml");
return new HttpEntity<>(xml, atomMap);
}
  1. 创建文件部分
private HttpEntity<InputStreamResource> createFilePart(InputStream file, String contentId, String contentType) {
MultiValueMap<String, String> fileMap = new LinkedMultiValueMap<>();
fileMap.add(HttpHeaders.CONTENT_TYPE, contentType);
fileMap.add("Content-ID", contentId);
return new HttpEntity<>(new InputStreamResource(file), fileMap);
}
  1. 准备您的请求
private HttpEntity<MultiValueMap<String, Object>> prepareRequest(InputStream file, String xml, String contentId, String contentType) {
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.add("atom", createAtomPart(xml));
bodyMap.add("file", createFilePart(file, contentId, contentType));
return new HttpEntity<>(bodyMap, createHeaders());
}
  1. 张贴
public ResponseEntity<String> sendPostRequest(InputStream file, String xml, String contentId, String contentType) throws ClientException {
HttpEntity<MultiValueMap<String, Object>> request = prepareRequest(file, xml, contentId, contentType);
ResponseEntity<String> response;
try {
response = restTemplate.postForEntity(uri, request, String.class);
} catch (HttpServerErrorException e) {
log.info("Error occurred on server side, reason:", e);
return new ResponseEntity<>(e.getResponseBodyAsString(), e.getStatusCode());
} catch (HttpClientErrorException e) {
throw new ClientException(e.getStatusCode(), e.getResponseBodyAsString(), e);
}
return response;
}

最新更新