Spring对POST内容进行处理的坑

Posted 邓志国

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring对POST内容进行处理的坑相关的知识,希望对你有一定的参考价值。

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

以上是关于Spring对POST内容进行处理的坑的主要内容,如果未能解决你的问题,请参考以下文章

2021-09-24 ruoyi框架中使用feign自定义服务,fegin使用遇到的坑

常用python日期日志获取内容循环的代码片段

spring-data-redis 使用过程中踩过的坑

分析动态代理给 Spring 事务埋下的坑

如何避免掉进spring事务不生效的坑中

如何使用 Spring 异常处理 POST REST 更正错误状态代码