RestTemplate 提交Multipartfile数组参数

项目场景:

项目场景:客户要求物流运输的签收单文件回传到客户系统

问题描述:

回传多文件是报错,调用不到客户系统

FileInputStream in = new FileInputStream("D:\\P210414170526708.jpg");
        FileInputStream in2 = new FileInputStream("D:\\ccc.jpg");
        MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
        postParameters.add("wayBillNo","T10000");
        List<MultipartFileResource> fileList = new ArrayList<>();
        fileList.add(new MultipartFileResource(in, "aaaaaaa.jpg"));
        String url = "http://localhost:8089/file/upload2";
        Map<String, Object> post = HttpRequestUtils.post(url, postParameters, new HashMap<>(), MediaType.MULTIPART_FORM_DATA);
        System.out.println(post);

# 报错:

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.io.FileDescriptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->com.henglu.common.entity.MultipartFileResource[“inputStream”]->java.io.FileInputStream[“fd”])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:293)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.writeInternal(AbstractGenericHttpMessageConverter.java:111)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:224)
at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:400)
at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:376)
at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:356)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:274)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:95)
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:955)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:721)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:435)
at com.henglu.common.utils.HttpRequestUtils.post(HttpRequestUtils.java:89)
at dahua.DahuaTest.test5(DahuaTest.java:173)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner 2. e v a l u a t e ( P a r e n t R u n n e r . j a v a : 268 ) a t o r g . s p r i n g f r a m e w o r k . t e s t . c o n t e x t . j u n i t 4. s t a t e m e n t s . R u n B e f o r e T e s t C l a s s C a l l b a c k s . e v a l u a t e ( R u n B e f o r e T e s t C l a s s C a l l b a c k s . j a v a : 61 ) a t o r g . s p r i n g f r a m e w o r k . t e s t . c o n t e x t . j u n i t 4. s t a t e m e n t s . R u n A f t e r T e s t C l a s s C a l l b a c k s . e v a l u a t e ( R u n A f t e r T e s t C l a s s C a l l b a c k s . j a v a : 70 ) a t o r g . j u n i t . r u n n e r s . P a r e n t R u n n e r . r u n ( P a r e n t R u n n e r . j a v a : 363 ) a t o r g . s p r i n g f r a m e w o r k . t e s t . c o n t e x t . j u n i t 4. S p r i n g J U n i t 4 C l a s s R u n n e r . r u n ( S p r i n g J U n i t 4 C l a s s R u n n e r . j a v a : 190 ) a t o r g . j u n i t . r u n n e r . J U n i t C o r e . r u n ( J U n i t C o r e . j a v a : 137 ) a t c o m . i n t e l l i j . j u n i t 4. J U n i t 4 I d e a T e s t R u n n e r . s t a r t R u n n e r W i t h A r g s ( J U n i t 4 I d e a T e s t R u n n e r . j a v a : 68 ) a t c o m . i n t e l l i j . r t . e x e c u t i o n . j u n i t . I d e a T e s t R u n n e r 2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner 2.evaluate(ParentRunner.java:268)atorg.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)atorg.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)atorg.junit.runners.ParentRunner.run(ParentRunner.java:363)atorg.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)atorg.junit.runner.JUnitCore.run(JUnitCore.java:137)atcom.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)atcom.intellij.rt.execution.junit.IdeaTestRunnerRepeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


# 原因分析:

分析了一下,是参数封装错了,数组参数提交的时候应该是把相同的key名称加入MultiValueMap中,这样就是提交了数组数据了


解决方案:

  • RestTemplate 请求封装

import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;

public final class HttpRequestUtils {
   //设置字符编码
   private static final String CHARSET = "UTF-8";

   private static RequestConfig defaultRequestConfig = RequestConfig
       .custom()
       //设置等待数据超时时间
       .setSocketTimeout(30000)
       //设置连接超时时间
       .setConnectTimeout(30000)
       //设置从连接池获取连接的等待超时时间
       .setConnectionRequestTimeout(30000)
       //.setStaleConnectionCheckEnabled(true)
       .build();

   //释放资源,httpResponse为响应流,httpClient为请求客户端
   private static void release(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient) throws IOException {
       if (httpResponse != null) {
           httpResponse.close();
       }
       if (httpClient != null) {
           httpClient.close();
       }
   }

   //get请求带参数、带请求头
   public static String get(String urlWithParams, Map<String, String> header) throws IOException {
       CloseableHttpClient httpClient = HttpClients.createDefault();
       HttpGet httpget = new HttpGet(urlWithParams);
       if (!MapUtils.isEmpty(header)) {
           header.forEach(httpget::addHeader);
       }
       CloseableHttpResponse response = httpClient.execute(httpget);
       HttpEntity entity = response.getEntity();
       String result = EntityUtils.toString(entity, CHARSET);
       httpget.releaseConnection();
       release(response, httpClient);
       return result;
   }

   public static String get(String urlWithParams) throws IOException {
       return get(urlWithParams, null);
   }

   //发送post请求,带json请求体和请求头
   public static String postJson(String url, String json, Map<String, String> headersMap) {
       RestTemplate restTemplate = new RestTemplate();
       HttpHeaders headers = new HttpHeaders();
       headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

       for (Map.Entry<String, String> entry : headersMap.entrySet()) {
           headers.add(entry.getKey(),entry.getValue());
       }
       org.springframework.http.HttpEntity<String> request = new org.springframework.http.HttpEntity<>(json, headers);
       ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
       return response.getBody();
   }
   //发送post请求,请求体和请求头
   public  static <T> Map<String, Object> post(String url, T paraT, Map<String, String> headersMap, MediaType mediaType) throws URISyntaxException {
       RestTemplate restTemplate = new RestTemplate();
       HttpHeaders headers = new HttpHeaders();
       if(mediaType != null) {
           headers.setContentType(mediaType);
       }

       for (Map.Entry<String, String> entry : headersMap.entrySet()) {
           headers.add(entry.getKey(),entry.getValue());
       }
       org.springframework.http.HttpEntity<T> request = new org.springframework.http.HttpEntity<>(paraT, headers);
       Map response = restTemplate.postForObject(url, request, Map.class);
       return response;
   }

}
  • 调用客户接口
 FileInputStream in = new FileInputStream("D:\\P210414170526708.jpg");
        FileInputStream in2 = new FileInputStream("D:\\cccc.jpg");
        MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
        postParameters.add("wayBillNo","T10000");
        postParameters.add("fileList", new MultipartFileResource(in, "P210414170526708.jpg"));
        postParameters.add("fileList", new MultipartFileResource(in2, "ccc.jpg"));
        String url = "http://localhost:8089/file/upload2";
        Map<String, Object> post = HttpRequestUtils.post(url, postParameters, new HashMap<>(), MediaType.MULTIPART_FORM_DATA);
        System.out.println(post);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MultipartFile数组是一种用来存储多个MultipartFile文件的数据结构。在给定的引用中,通过定义多个MultipartFile对象和MultipartFile数组,并将文件放入数组中,实现了将多个文件存储在一个数组中的目的。 在引用中,首先定义了四个MultipartFile文件对象(file1, file2, file3, file4),然后定义了两个MultipartFile数组对象(photoApproveMaterials1和photoApproveMaterials2),并将文件对象放入数组中。数组photoApproveMaterials1中包含了file1和file2,数组photoApproveMaterials2中包含了file3和file4。 另外,引用中还给出了将photoApproveMaterials1和photoApproveMaterials2合并到一个更大的MultipartFile数组(multipartFiles)中的方法。通过计算两个数组的长度(multLength),然后使用嵌套的循环将文件对象逐个添加到multipartFiles数组中,实现了将多个数组合并成一个数组的操作。最后,通过遍历multipartFiles数组,可以获取每个文件的名称和大小。 如果你有更好的方法或建议,可以在评论中分享。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [两个 MultipartFile 数据类型 合成一个&&base64字符转MultipartFile数组类型](https://blog.csdn.net/qq_24023751/article/details/113859014)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [byte数组与base64字符互转](https://download.csdn.net/download/Kien_tang/88035023)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值