标题可能看起来很普通,但是没有一个适合我的问题.
我有一个REST服务,它接受多部分形式的常规参数和文件.
我想使用resttemplate将数据和文件发送到上述rest服务.
直到我发送正常的字符串数据为止,没有任何问题.一旦我添加了发送字节的代码,那么我开始收到400错误的请求错误.
如果我注释了发送ByteArrayResource的代码,那么它将开始为正常参数工作.
下面是示例代码
休息服务控制器
@RestController
@RequestMapping(value="/ticket")
public class UserTicketController {
@RequestMapping(value="/createTicket.do",method={RequestMethod.POST},
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE},headers={"content-type="+MediaType.MULTIPART_FORM_DATA_VALUE})
public void createTicket(@ModelAttribute ServiceDeskRequest serviceDeskRequest, HttpServletRequest request,HttpServletResponse response) throws Exception{
}
}
Servicedeskrequest模型属性为
public class ServiceDeskRequest implements Serializable{
private String jsonData;
private MultipartFile attachment;
}
应用程序的context.xml
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
客户端代码
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, Object> requestParamerterMap = new LinkedMultiValueMap<String, Object>();
requestParamerterMap.add("jsonData", jsonData);
MultipartFile attachment = userRequest.getAttachment();
if(attachment!=null && attachment.getOriginalFilename()!=null) {
ByteArrayResource byteArrayResource = new ByteArrayResource(attachment.getBytes(), attachment.getOriginalFilename());
requestParamerterMap.add("attachment", byteArrayResource);
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(requestParamerterMap, headers);
String response = restTemplate.postForObject(targetUrl, requestEntity, String.class);
解决方法:
我想到了.这个难题有两部分.服务代码未更改.
>提供正确的转换器以重新模板.在默认转换列表中,spring不会添加FormHttpMessageConverter.
FormHttpMessageConverter converter = new FormHttpMessageConverter();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(converter);
>重写bytearrayresource类.请注意,您需要重写getFilename方法,以便可以在服务端接收文档名称.
public class MultipartByteArrayResource extends ByteArrayResource{
private String fileName;
public MultipartByteArrayResource(byte[] byteArray) {
super(byteArray);
}
public String getFilename() {
return fileName;
}
public void setFilename(String fileName) {
this.fileName= fileName;
}
}
上述更改后,客户端代码将是
FormHttpMessageConverter converter = new FormHttpMessageConverter();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(converter);
MultiValueMap<String, Object> requestParamerterMap = new LinkedMultiValueMap<String, Object>();
requestParamerterMap.add("jsonData", jsonData);
MultipartFile attachment = userRequest.getAttachment();
if(attachment!=null && attachment.getOriginalFilename()!=null) {
//ByteArrayResource byteArrayResource = new ByteArrayResource(attachment.getBytes(), attachment.getOriginalFilename());
MultipartByteArrayResource resource = new MultipartByteArrayResource(attachment.getBytes());
//pass file name sepratly
resource.setFilename(attachment.getOriginalFilename());
requestParamerterMap.add("attachment", resource);
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(requestParamerterMap, headers);
String response = restTemplate.postForObject(targetUrls.get("sdCreateTicketsUrl"), requestEntity, String.class);