2017-08-02 72 views
1

标题可能看起来很普遍,但没有一个适合我的问题。通过resttemplate在春天休息服务发送文件

我有一个休息服务接受正常参数和文件的形式multipart。

我想用resttemplate发送数据和文件到上面的休息服务。

直到我发送正常字符串数据的时间没有问题。一旦我添加发送字节的代码,然后我开始得到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> 

客户小号ide代码

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

回答

0

首先,value="/createTicket.do"是远离REST约定。 /ticket也是如此。 创建一张票应该通过POST到URL完成:.../tickets/

1

我想通了。这个谜题中有两件。服务代码没有变化。

  1. 提供右转换器resttemplate。在默认转换列表中,Spring不添加FormHttpMessageConverter。

    FormHttpMessageConverter converter = new FormHttpMessageConverter(); 
    
        RestTemplate restTemplate = new RestTemplate(); 
        restTemplate.getMessageConverters().add(converter); 
    
  2. 覆盖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);