有次和某第三方公司调试接口,他们的协议很奇葩:Content-Type用application/x-www-form-urlencoded,然而内容却是把图片内容直接写了进去。在Spring中用
@RequestBody byte[] data
去接数据的时候,发现内容都被URLEncode编码了,无法取得原始的流。跟踪源码到:
RequestResponseBodyMethodProcessor
。。。。
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
Object arg = this.readWithMessageConverters(inputMessage, parameter, paramType);
Spring把request包装了一层传递了下去,跟踪进去,他的getBody方法
public InputStream getBody() throws IOException {
return (InputStream)(isFormPost(this.servletRequest) ? getBodyFromServletRequestParameters(this.servletRequest) : this.servletRequest.getInputStream());
}
看isFormPost
private static boolean isFormPost(HttpServletRequest request) {
String contentType = request.getContentType();
return contentType != null && contentType.contains("application/x-www-form-urlencoded") && HttpMethod.POST.matches(request.getMethod());
}
看getBodyFromServletRequestParameters方法
private static InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
Writer writer = new OutputStreamWriter(bos, "UTF-8");
Map<String, String[]> form = request.getParameterMap();
Iterator nameIterator = form.keySet().iterator();
while(nameIterator.hasNext()) {
String name = (String)nameIterator.next();
List<String> values = Arrays.asList((Object[])form.get(name));
Iterator valueIterator = values.iterator();
while(valueIterator.hasNext()) {
String value = (String)valueIterator.next();
writer.write(URLEncoder.encode(name, "UTF-8"));
if (value != null) {
writer.write(61);
writer.write(URLEncoder.encode(value, "UTF-8"));
if (valueIterator.hasNext()) {
writer.write(38);
}
}
}
if (nameIterator.hasNext()) {
writer.append('&');
}
}
writer.flush();
return new ByteArrayInputStream(bos.toByteArray());
}
无解,只能让他们修改调用协议,不要用application/x-www-form-urlencoded