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);
上一篇: 全方位解读DLL文件—编写DLL