嗨,我需要使用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]
请通知更改以使客户端代码正常工作。
经过多次试验和错误,能够找到相同的解决方案。
客户端代码:
@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;
}