日志级别对springMvc参数解析的影响

最近遇到测试环境和生成环境参数解析结果不一样的问题,最后发现是日志级别导致的,写个简单的demo记录下。
测试方法:

@PostMapping("test")
    public String test(HttpServletRequest request) throws Exception{
        InputStream inputStream = request.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null){
            sb.append(line);
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

传参方式为application/x-www-form-urlencoded,
在spring日志级别大于DEBUG时,可以正常解析出参数,测试环境日志级别为DEBUG时,无法获取到参数。

原因

在debug打开时,DispatcherServlet对请求参数进行了解析并打印:

    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logRequest(request);
        ........
}
private void logRequest(HttpServletRequest request) {
        LogFormatUtils.traceDebug(logger, traceOn -> {
            String params;
            if (isEnableLoggingRequestDetails()) {
                params = request.getParameterMap().entrySet().stream()
                        .map(entry -> entry.getKey() + ":" + Arrays.toString(entry.getValue()))
                        .collect(Collectors.joining(", "));
            }
        ......

在debug打开时,会调用request.getParameterMap(),会对参数进行解析,在tomcat的Request的parseParameters方法中,对于application/x-www-form-urlencoded传参的POST,会读取Body的数据来解析:

protected int readPostBody(byte[] body, int len)
            throws IOException {
        int offset = 0;
        do {
            int inputLen = getStream().read(body, offset, len - offset);
            if (inputLen <= 0) {
                return offset;
            }
            offset += inputLen;
        } while ((len - offset) > 0);
        return len;

    }

而BIO中InputStream是单向的,无法重复读取,所以在方法中再读是读不到的。

由此可见,即使是简单的日志级别的不同,也可能引起业务逻辑的不一样。测试环境最好和正式环境一模一样,才能尽可能提前发现问题。

你可能感兴趣的:(日志级别对springMvc参数解析的影响)