【问题标题】:How to post Atom entry and File using RestTemplate如何使用 RestTemplate 发布 Atom 条目和文件
【发布时间】:2020-12-28 00:16:09
【问题描述】:

我正在尝试使用 RestTemplate 发布带有多部分/相关请求的 Atom xml 和文件。 问题是 - 是否可以更改部分的标题,例如在原子部分的边界之后显示的 Content-Type 或在文件部分添加 Content-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 的部分具有 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);

提前谢谢你

【问题讨论】:

    标签: java spring resttemplate multipart atom-feed


    【解决方案1】:

    好的,我找到了适合我的解决方案。我将尝试逐步解释我是如何做到的。

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

    【讨论】:

      猜你喜欢
      • 2020-11-17
      • 1970-01-01
      • 2013-03-24
      • 2017-09-25
      • 2016-03-07
      • 2017-10-30
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多