有次和某第三方公司调试接口,他们的协议很奇葩: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

posted on 2018-04-28 08:21  邓志国  阅读(333)  评论(0编辑  收藏  举报