java-通过resttemplate通过Spring Rest服务发送文件

标题可能看起来很普通,但是没有一个适合我的问题.

我有一个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);
上一篇:restTemplate源码解析(四)执行ClientHttpRequest请求对象


下一篇:java-如何与使用keycloak提供网页的客户端一起使用计划任务?