用于多部分REST操作的客户端代码

时间:2019-03-15 10:29:28

标签: spring rest upload resttemplate multipart

嗨,我需要使用一个REST操作,该操作接受xml有效负载和pdf文件。基本上,JAXB对象将转换为xml字符串并上传到xml文件中。因此,在多部分请求中,将上传xml文件和pdf文件。

REST操作服务器端代码如下:

服务器端:

public class CompanyType extends MediaType {

public final static final XML_STRING = "applicaiton/company+xml";

}

@POST
@Path("/upload")
@Consumes("multipart/mixed")
@Produces(CompanyType.XML_STRING)
public UploadResponseObject upload(MultiPart multiPart){

UploadRequestObject req = multiPart.getBodyParts().get(0).getEntityAs(UploadRequestObject.class);
            BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(1).getEntity();
            byte[] pdfBytes = IOUtils.toByteArray(bpe.getInputStream());
....
....
}

客户端代码以使用REST操作:

@Autowired
private RestTemplate rt;

public UploadResponseObject callMultipartUploadOperation(UploadRequestObject req, java.io.File target) throws Exception {
        String url = "http://<host-name>:<port>/service-name/upload");

        MultiValueMap<String, Object> mv = new LinkedMultiValueMap<String, Object>();

        this.rt = new RestTemplate();
        this.rt.setMessageConverters(getMessageConverter());
        String id = <random number generated from 1 to 50000>;

        // Add xml entity
        org.springframework.http.HttpHeaders xmlFileHeaders = new org.springframework.http.HttpHeaders();
        xmlFileHeaders.add(MeditType.CONTENT_TYPE, "applicaiton/company+xml");
        HttpEntity<String> xmlFile = new HttpEntity<String>(createXMLString(req), xmlFileHeaders);
        mv.add(id + ".xml", xmlFile);

        // Add pdf file     

        org.springframework.http.HttpHeaders fileHeaders = new org.springframework.http.HttpHeaders();
        fileHeaders.add(MediaType.CONTENT_TYPE, "application/pdf");
        FileSystemResource fsr = new FileSystemResource(target);
        HttpEntity<FileSystemResource> fileEntity = new HttpEntity<FileSystemResource>(
                fsr, fileHeaders);
        String filename = target.getName();
        mv.add(filename, fileEntity);

        HttpEntity<UploadRequestObject> ereq = new HttpEntity<UploadRequestObject>(req, getRequestHeaders());
        ResponseEntity<UploadResponseObject> res= this.restTemplate.postForEntity(url, ereq, UploadResponseObject.class);       
        return res.getBody();
    }

private List<HttpMessageConverter<?>> getMessageConverter() {
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setClassesToBeBound(UploadResponseObject.class);
        MarshallingHttpMessageConverter mhmc = new MarshallingHttpMessageConverter(jaxb2Marshaller);
        List<org.springframework.http.MediaType> supportedMediaTypes = new ArrayList<org.springframework.http.MediaType>();
        supportedMediaTypes.add(new org.springframework.http.MediaType("application", "company+xml"));
        mhmc.setSupportedMediaTypes(supportedMediaTypes);
        messageConverters.add(mhmc);

        // Add Form and Part converters
        FormHttpMessageConverter fmc = new FormHttpMessageConverter();
        fmc.addPartConverter(new Jaxb2RootElementHttpMessageConverter());
        messageConverters.add(fmc);

        return messageConverters;
    }

从客户端代码执行以下行时,

ResponseEntity<UploadResponseObject> res= this.rt.postForEntity(url, ereq, UploadResponseObject.class); 

引发以下异常

org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter 
found for request 
type [org..types.UploadRequestObject] 
and content type [application/company+xml]

请告知更改以使客户端代码正常工作。

1 个答案:

答案 0 :(得分:0)

经过反复试验,能够找到相同的解决方案。

客户端代码:

@Autowired
    private RestTemplate rt;

public UploadResponseObject callMultipartUploadOperation(UploadRequestObject req, java.io.File target) throws Exception {
        String url = "http://<host-name>:<port>/service-name/upload");

        MultiValueMap<String, Object> mv = new LinkedMultiValueMap<String, Object>();

        this.rt = new RestTemplate();
        this.rt.setMessageConverters(getMessageConverter());
        String id = <random number generated from 1 to 50000>;

        // Add xml entity
        org.springframework.http.HttpHeaders xmlFileHeaders = new org.springframework.http.HttpHeaders();
        xmlFileHeaders.add(MeditType.CONTENT_TYPE, "applicaiton/company+xml");
        HttpEntity<String> xmlFile = new HttpEntity<String>(createXMLString(req), xmlFileHeaders);
        mv.add(id + ".xml", xmlFile);

        // Add pdf file     

        org.springframework.http.HttpHeaders fileHeaders = new org.springframework.http.HttpHeaders();
        fileHeaders.add(MediaType.CONTENT_TYPE, "application/pdf");
        FileSystemResource fsr = new FileSystemResource(target);
        HttpEntity<FileSystemResource> fileEntity = new HttpEntity<FileSystemResource>(
                fsr, fileHeaders);
        String filename = target.getName();
        mv.add(filename, fileEntity);

        HttpEntity<UploadRequestObject> ereq = new HttpEntity<UploadRequestObject>(req, getRequestHeaders());
        ResponseEntity<UploadResponseObject> res= this.restTemplate.postForEntity(url, ereq, UploadResponseObject.class);       
        return res.getBody();
    }

消息转换器:

private List<HttpMessageConverter<?>> getMessageConverter() {
            List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
            Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
            jaxb2Marshaller.setClassesToBeBound(UploadResponseObject.class);
            MarshallingHttpMessageConverter mhmc = new MarshallingHttpMessageConverter(jaxb2Marshaller);
            List<org.springframework.http.MediaType> supportedMediaTypes = new ArrayList<org.springframework.http.MediaType>();
            supportedMediaTypes.add(new org.springframework.http.MediaType("application", "company+xml"));
            supportedMediaTypes.add(new org.springframework.http.MediaType("multipart", "form-data"));
            mhmc.setSupportedMediaTypes(supportedMediaTypes);
            messageConverters.add(mhmc);

            // Add Form and Part converters
            FormHttpMessageConverter fmc = new FormHttpMessageConverter();
            fmc.addPartConverter(new Jaxb2RootElementHttpMessageConverter());
            fmc.addPartConverter(new ResourceHttpMessageConverter());
            messageConverters.add(fmc);

            return messageConverters;
        }

请求标头:

private org.springframework.http.HttpHeaders getRequestHeaders(String contentType) throws Exception {
            ....
            .....
            org.springframework.http.HttpHeaders httpHeaders = new org.springframework.http.HttpHeaders();
            httpHeaders.set("Accept", "applicaiton/company+xml");
            httpHeaders.set("Content-Type", "multipart/form-data");
            String consumer = "<AppUserId>";
            httpHeaders.set("consumer", consumer);
            String tmStamp= getCurrentTimeStamp();
            httpHeaders.set("timestamp", tmStamp);
            ...
            ...
            return httpHeaders;
        }