2017-08-02 53 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);