为了账号安全,请及时绑定邮箱和手机立即绑定

使用RestTemplate请求将多部分文件作为POST参数发送

/ 猿问

使用RestTemplate请求将多部分文件作为POST参数发送

呼啦一阵风 2019-11-29 10:33:07

我正在使用Spring 3和RestTemplate。我基本上有两个应用程序,其中一个必须将值发布到另一个应用程序。通过休息模板。


当要发布的值是String时,它是完美的工作,但是当我必须发布混合和复杂的参数(例如MultipartFiles)时,我会收到转换器异常。


例如,我有这个:


App1- PostController:


@RequestMapping(method = RequestMethod.POST)

public String processSubmit(@ModelAttribute UploadDTO pUploadDTO, 

        BindingResult pResult) throws URISyntaxException, IOException {

    URI uri = new URI("http://localhost:8080/app2/file/receiver");


    MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();

    mvm.add("param1", "TestParameter");

    mvm.add("file", pUploadDTO.getFile()); // MultipartFile


    Map result = restTemplate.postForObject(uri, mvm, Map.class);

    return "redirect:postupload";

}

另一方面...我有另一个Web应用程序(App2),它从App1接收参数。


App2- ReceiverController


@RequestMapping(value = "/receiver", method = { RequestMethod.POST })

public String processUploadFile(

        @RequestParam(value = "param1") String param1,

        @RequestParam(value = "file") MultipartFile file) {


    if (file == null) {

        System.out.println("Shit!... is null");

    } else {

        System.out.println("Yes!... work done!");

    }

    return "redirect:postupload";

}

我的application-context.xml:


<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">

    <property name="messageConverters">

        <list>

            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />

            <bean class="org.springframework.http.converter.FormHttpMessageConverter" />

            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />

            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />

        </list>

    </property>

</bean>



所以我的问题是:

  1. 是否可以使用POST通过RestTemplate发送MultipartFile?

  2. 我必须使用某些特定的转换器来发送此类对象吗?我的意思是在配置中要使用一些MultipartFileHttpMessageConverter吗?


查看完整描述

3 回答

?
牛魔王的故事

解决此问题而无需使用需要磁盘上文件的FileSystemResource的一种方法是使用ByteArrayResource,这样您就可以在帖子中发送字节数组(此代码在Spring 3.2.3中有效):


MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();

final String filename="somefile.txt";

map.add("name", filename);

map.add("filename", filename);

ByteArrayResource contentsAsResource = new ByteArrayResource(content.getBytes("UTF-8")){

            @Override

            public String getFilename(){

                return filename;

            }

        };

map.add("file", contentsAsResource);

String result = restTemplate.postForObject(urlForFacade, map, String.class);

我重写ByteArrayResource的getFilename,因为如果我不得到空指针异常(显然,这取决于java激活.jar是否在类路径中,如果存在,它将使用文件名来尝试确定内容类型)


查看完整回答
反对 回复 2019-11-29
?
LEATH

前几天,我也遇到了同样的问题。Google搜索将我带到了这里和其他几个地方,但没有一个提供解决此问题的方法。我最终将上传的文件(MultiPartFile)保存为tmp文件,然后使用FileSystemResource通过RestTemplate上传它。这是我使用的代码


String tempFileName = "/tmp/" + multiFile.getOriginalFileName();

FileOutputStream fo = new FileOutputStream(tempFileName);


fo.write(asset.getBytes());    

fo.close();   


parts.add("file", new FileSystemResource(tempFileName));    

String response = restTemplate.postForObject(uploadUrl, parts, String.class, authToken, path);   



//clean-up    

File f = new File(tempFileName);    

f.delete();

我仍在寻找解决此问题的更优雅的方法。


查看完整回答
反对 回复 2019-11-29
?
扬帆大鱼

MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();

parts.add("name 1", "value 1");

parts.add("name 2", "value 2+1");

parts.add("name 2", "value 2+2");

Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");

parts.add("logo", logo);

Source xml = new StreamSource(new StringReader("<root><child/></root>"));

parts.add("xml", xml);


template.postForLocation("http://example.com/multipart", parts);


查看完整回答
反对 回复 2019-11-29

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信