源码分析SpringMvc日志打印被忽略输出问题

2022-11-13 15:11:58 源码 输出 忽略

1.写在前面

在java的开发过程中,涉及到JAVA WEB的开发,基本上都是走spring这一套了。

我们之前一般来说,都会说mvc:Model(模型业务)、View(视图界面)、Controller(控制器)。这个学习java开发的,应该都懂吧,这里就不多说了。

这里,我们先着重解析下Controller:

Controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

那作为控制层框架,一般有springMVC、struts2,struts2一些老的框架可能会用到,新的一些框架,基本就很少见了,都走springmvc这套了。

springmvc,我们就用得多了,但是对于SpringMvc日志打印被忽略输出的问题,有无人研究过呢?

嘿嘿,巧了,这个问题,哥们研究过了,那我们今天就来分析下这个问题喽!!!

2.问题引出

DEBUG org.springframework.WEB.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor Read "application/JSON;charset=UTF-8" to [QueryData(pageNo=1, pageSize=10, sortField=, sortOrder=asc, params={Q_XM_S_EQ=llsydn, Q_SJH_S_EQ=135 (truncated)...]

可以看到控制台打印的日志,出现了 (truncated)...

这里对应的前端页面的功能是这样的:

很明显,springmvc接收到前端传进来的参数,然后会在控制台打印相关的日志。但是这里的参数,日志打印是不完整的。出现了 (truncated)...截取的问题。

看到这,有好奇心的小伙伴,估计都想探个究竟了吧?(别说你不想?)

好嘛好嘛,是我自己想探个究竟啦!!!(卑微)

那这里我们先从源码中,找到被截取的地方喽。

3.截取源码分析

首先这里,要如何进行源码查看呢?这里我们可以从打印的日志入手......

  • RequestResponseBodyMethodProcessor

进入到RequestResponseBodyMethodProcessor类中,查看log打印日志的地方,并没有发现打印日志的代码。

那我们就将该类所有的方法都打上断点(主要是该类不算很大),再发一个请求,断点调试一下:

  • 进入到readWithMessageConverters,方法里面来了

经过一步步执行,执行到

Object arg = readWithMessageConverters(inputMessage, parameter, paramType);

可以看到控制台,就打印了我们刚才的日志

那这里,我们就可以继续往readWithMessageConverters,里面进行查看(再发一个请求)

经过一步步执行,执行到LogFORMatUtils.traceDebug

可以看到控制台,就打印了我们刚才的日志

那这里,将其他的断点去掉,再这里点一个,然后再发一个请求进来。

嘿嘿,看到这,估计大家都知道了吧。

当参数字符超过100,这里就会截取。

看到这里,我们是通过源码,一步步的找到最终的原因,那这里只是提供一个方法,思路。

大家伙可以自己动手去调试一波,毕竟也不难,哈哈!

这里贴一下,最终的业务逻辑代码,如下:

(limitLength && str.length() > 100 ? str.substring(0, 100) + " (truncated)..." : str);

可以看到,当limitLength为true时,str长度大于100,就会截取前100个字符,后面再拼接 (truncated)...

那我们不禁会想,嘿,哥们想办法把limitLength的值,改为false,不就永远都不会截取输出日志了吗?

嗯嗯,是这么一回事,那这个limitLength的值,如何改?怎么来的?

只能通过源码分析一波了,好啦,这个任务就交给各位了,动手去干活吧!

4.截取问题处理

public boolean isTraceEnabled(Marker marker) {
    final FilterReply decision = callTurboFilters(marker, Level.TRACE);
    if (decision == FilterReply.NEUTRAL) {
        return effectiveLevelInt <= Level.TRACE_INT;
    } else if (decision == FilterReply.DENY) {
        return false;
    } else if (decision == FilterReply.ACCEPT) {
        return true;
    } else {
        throw new IllegalStateException("Unknown FilterReply value: " + decision);
    }
}

通过查看这里的代码,就是这里返回上面limitLength的值。

可以看到这里,我们的改变decision的值,让它变成FilterReply.ACCEPT,这样这里就能返回true 了。

callTurboFilters,如何改呢?这里我百度找到了一个方式:

Logback 使用TurboFilter实现日志级别等内容的动态修改操作。

  • 定义TurboFilter
public class SpringMvcFilter extends TurboFilter {
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable throwable) {
        if (logger.getName().equals("org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor")) {
            return FilterReply.ACCEPT; //返回accept
        }
        return FilterReply.NEUTRAL;
    }
}
  • logback的配置xml
<configuration>
    <turboFilter class="com.llsydn.log.filter.SpringMvcFilter" />
    ......
</configuration>

看看最终效果:

DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor Read "application/json;charset=UTF-8" to [QueryData(pageNo=1, pageSize=10, sortField=, sortOrder=asc, params={Q_XM_S_EQ=llsydn, Q_SJH_S_EQ=135****4606]

可以看到,springmvc打印的日志,正常了,不再截取了。

好了,以上就是 SpringMvc日志打印被忽略输出问题分析(源码分析) 的分享了。

个人实操可能也不够全面,班门弄斧了。

以上就是源码分析SpringMvc日志打印被忽略输出问题的详细内容,更多关于SpringMvc日志打印被忽略输出的资料请关注其它相关文章!

相关文章