您好,欢迎来到年旅网。
搜索
您的当前位置:首页调用 request.getParameter 之后再调用 request.getInputStream 取不到流数据

调用 request.getParameter 之后再调用 request.getInputStream 取不到流数据

来源:年旅网

调用 request.getParameter 之后再调用 request.getInputStream 取不到流数据

2016年03月16日 12:45:56  阅读数 6711

0x00 问题描述 & 背景

随着项目的推进,增加了权限控制模块,具体控制到接口层(controller)。每次调用接口时需要校验用户是否有权限。用的方案是spring的。

前端(APP)所有的请求都会携带参数sessionId,作为用户的标识。其中Get请求参数是通过url传递的,post请求参数是通过二进制流传递的。

在获取sessionId的时候先执行request.getParameter("sessionId"),如果没有拿到sessionId,则调用request.getInputStream()获取流信息。具体代码如下:

private String getSessionId(HttpServletRequest request) {
    String sessionId = request.getParameter("sessionId");
    if (sessionId == null) {
        // 参数也可能为sessionid
        sessionId = request.getParameter("sessionid");
    }
    if (sessionId == null) {
        // post请求
        String data = getRequestStringData(request);
        System.out.println("data = " + data);
        if (data.length() > 0) {
            // TODO get SeesionId from json
        }
    }
    return sessionId;
}

private String getRequestStringData(HttpServletRequest request) {
    StringBuffer info = new java.lang.StringBuffer();
    InputStream in = null;
    try {
        in = request.getInputStream();
        BufferedInputStream buf = new BufferedInputStream(in);
        byte[] buffer = new byte[1024];
        int iRead;
        while ((iRead = buf.read(buffer)) != -1) {
            info.append(new String(buffer, 0, iRead, "utf-8"));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != in) {
                in.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return info.toString();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

测试发现post请求始终拿不到sessionId,加点日志发现整个流信息都为空。

0x01 问题排查过程

0x02 解决方案

在获取sessionId的时候先判断是Post请求还是Get请求,如果是Get请求就调用getParameter方法,Post请求则调用getInputStream方法。

还有一点需要注意,流数据只能读一次,在中获取完流数据之后需要回写到request,以便controller使用。代码如下:

private String getSessionId(HttpServletRequest request) {
    String sessionId = "";
    logger.info("请求方式:"+request.getMethod());
    if ("GET".equalsIgnoreCase(request.getMethod())) {
        sessionId = request.getParameter("sessionId");
        if (sessionId == null) {
            // 参数也可能为sessionid
            sessionId = request.getParameter("sessionid");
        }
    } else if ("POST".equalsIgnoreCase(request.getMethod())) {
        // post请求
        String data = getRequestStringData(request);
        request.setAttribute("postData", data); // 流数据回写
        if (data.length() > 0) {
            JSONObject jsonObject = JSONObject.fromObject(data);
            sessionId = jsonObject.getString("sessionId");
        }
    }
    return sessionId;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

0x03 后记 & 疑问

  1. 如果哪位看官有更深的理解,欢迎指教。
  2. App端都是调用自带SDK发送的post请求,在问题修复之前,为什么App发送的请求息拿不到流信息而postman发送的则能拿到?烦请有研究的同学告知。

博文

  •  看看请求的contentType什么?如果为application/x-www-form-urlencoded;就有可能请求的数据在request.getParameterMap()中的,而不在流当中的~

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务