浅析request.getInputStream()得到的流及接参流程

  在 SpringSecurity 的自定义登录拦截中,使用了 jackson 去获取请求流解析成实体类实例对象。如:

// 登录是否含手机号
User voUser = new ObjectMapper().readValue(req.getInputStream(), User.class);
if (voUser == null || voUser.getPhoneNum() == null) {
    throw new AuthenticationServiceException("请输入手机号");
}

  Jackson已经研究了一下,看这篇:SpringSecurity登录报错403问题:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field异常、及 Jackson 的使用

  所以接下来了解一下:req.getInputStream() 这个知识。

一、编码方式:"multipart/form-data"

  浏览器采用了一种编码方式,即 "multipart/form-data" 的编码方式,采用这种方式,浏览器可以很容易将表单内的数据和文件放在一起发送。

  这种编码方式先定义好一个不可能在数据中出现的字符串作为分界符,然后用它将各个数据段分开,而对于每个数据段都对应着 HTML 页面表单中的一个 Input 区,包括一个 content-disposition 属性,说明了这个数据段的一些信息,如果这个数据段的内容是一个文件,还会有 Content-Type 属性,然后就是数据本身。

  我们可以用request.getInputStream()或request.getReader()得到提交的数据,但想要得到文件内容,还需要我们自己解析。

二、request.getInputStream()接参流程

1、spring接到浏览器传来的post请求所传进来的参数都在request里

@RequestMapping(value = PROXY_URL, method = RequestMethod.POST, produces = PRODUCES)
public Object proxy(final HttpServletRequest request, final HttpServletResponse response) {
  String json = new String(readInputStream(request.getInputStream()), "UTF-8");
}

  此时debug查看request.getInputStream()的值是全部请求信息,但是并非我们想要是参数

  所以我们要对结果解析:readInputSream()是解析方法

2、结果解析

public static byte[] readInputStream(InputStream inStream) throws Exception {
    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    boolean var3 = false;

    int len;
    while((len = inStream.read(buffer)) != -1) {
        outSteam.write(buffer, 0, len);
    }

    outSteam.close();
    inStream.close();
    return outSteam.toByteArray();
}

  inStream.read(buffer)读取数据赋值给buffer

  outSteam的结果就是我们想要的数据了。

  注意:这里的json格式的数据是前端定义好传进来的,和后台对 IO 流的解析无关。

  关于 IO 流的基础知识可以看这篇博客:Java里的IO基础知识笔记:IO流、字节流/字符流、File对象读取、输入流/输出流(使用过后及时关闭、缓冲区)、Filter模式、ZIP操作、读取classpath资源的意义、序列化/反序列化、Reader/Writer、使用Files工具类及其局限性

原文地址:https://www.cnblogs.com/goloving/p/14922208.html