I once debugged the interface with a third-party company, and their protocol was very strange: the Content-Type used application/x-www-form-urlencoded, but the content was directly written in the image content. Used in Spring
@RequestBody byte[] data
When receiving the data, it was found that the content was encoded by URLEncode, and the original stream could not be obtained. Trace the source code to:
RequestResponseBodyMethodProcessor 。。。。 ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest); Object arg = this.readWithMessageConverters(inputMessage, parameter, paramType);
Spring wraps the request and passes it on, tracks it, and his getBody method
public InputStream getBody() throws IOException { return (InputStream)(isFormPost(this.servletRequest) ? getBodyFromServletRequestParameters(this.servletRequest) : this.servletRequest.getInputStream()); }
see 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()); }
See getBodyFromServletRequestParameters method
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()); }
There is no solution, only let them modify the calling protocol, do not use application/x-www-form-urlencoded