簡體   English   中英

如何使用 RestTemplate 發布 Atom 條目和文件

[英]How to post Atom entry and File using RestTemplate

我正在嘗試使用 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。

現在它看起來如下所示,但原子部分具有 Content-Type: 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. 創建原子 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM