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

目录
  • 1.写在前面
  • 2.问题引出
  • 3.截取源码分析
  • 4.截取问题处理

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日志打印被忽略输出的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringMVC日期类型接收空值异常问题解决方法

    最近遇到SpringMVC写个controller类,传一个空串的字符类型过来,正常情况是会自动转成date类型的,因为数据表对应类类型就是date的 解决方法是在controller类的后面加个注解: @InitBinder protected void initDateFormatBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); binde

  • SpringMVC框架中使用Filter实现请求日志打印方式

    目录 查找资料后确定两种技术方案 1. 使用AOP对所有Controller的方法进行环绕通知处理: 2. 使用Filter拦截所有的Request和Response,并获取body. 最后选择了第二种方式,具体实现记录如下. 具体实现 日志记录过滤器 public class RequestFilter implements Filter{private static final String LOG_FORMATTER_IN = "请求路径:{%s},请求方法:{%s},参数:{%s},来源

  • springmvc接收参数为日期类型

    用单个Date类型接收日期类型时,会出现报错,加上initBinder的方法 意思是将所有传入的参数都通过此方法,如果过是日期通过日期格式化器进行格式化 如果是接收类型为对象内的属性为Date类型时 直接在属性双加上注解,就可以进行转化日期格式

  • SpringMVC如何把后台文件打印到前台

    实现效果如下: 代码为: @RequestMapping(value = "/tools/printContract") public void cell(HttpServletResponse response,HttpServletRequest request,String outName) { //根据outName获取到保存在服务器上的文件 String filePath = request.getSession().getServletContext().getRealPa

  • 解决springmvc整合Mybatis的Log4j日志输出问题

    springmvc整合Mybatis的Log4j日志输出 当我们进行web开发的时候总是看到配置的log4j日志在控制台无法显示mybatis的主要是指sql.参数.结果,出现这种问题有两种情况: 第一种情况 下面文档描述的mybatis本身内置很多种日志框架使用,所以如果我们要用具体哪个日志框架,就需要进行相应mybatis配置,或者就是按照mybatis本身规则运行. 问题在这里文档:http://mybatis.github.io/mybatis-3/zh/logging.html 配置方

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

    目录 1.写在前面 2.问题引出 3.截取源码分析 4.截取问题处理 1.写在前面 在java的开发过程中,涉及到java web的开发,基本上都是走spring这一套了. 我们之前一般来说,都会说mvc:Model(模型业务).View(视图界面).Controller(控制器).这个学习java开发的,应该都懂吧,这里就不多说了. 这里,我们先着重解析下Controller: Controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何

  • MyBatis源码分析之日志logging详解

    前言 本文介绍个人对 logging 包下源码的理解.分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 logging 配置加载 我们先从日志的配置加载开始阅读, MyBatis 的各项配置的加载过程都可以从 XMLConfigBuilder 类中找到,我们定位到该类下的日志加载方法 loadCustomLogImpl: private void loadCustomLogImpl(Properties props) { // 从 MyBatis 的 TypeAliasRegist

  • MyBatis源码分析之日志记录详解

    一 .概述 MyBatis没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的Log级别,且各不相同,但MyBatis统一提供了trace.debug.warn.error四个级别: 自动扫描日志实现,并且第三方日志插件加载优先级如下:slf4J → commonsLoging → Log4J2 → Log4J → JdkLog; 日志的使用要优雅的嵌入到主体功能中: 二.设计模式 将各种日志组件如(slf4J ,commonsLoging ,Log4J2 , Log4J

  • Python日志打印里logging.getLogger源码分析详解

    实践环境 WIN 10 Python 3.6.5 函数说明 logging.getLogger(name=None) getLogger函数位于logging/__init__.py脚本 源码分析 _loggerClass = Logger # ...略 root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) # ...略 def getLogger(name=None): "&quo

  • 深入理解框架背后的原理及源码分析

    目录 问题1 问题2 总结 近期团队中同学遇到几个问题,想在这儿跟大家分享一波,虽说不是很有难度,但是背后也折射出一些问题,值得思考. 开始之前先简单介绍一下我所在团队的技术栈,基于这个背景再展开后面将提到的几个问题,将会有更深刻的体会. 控制层基于SpringMvc,数据持久层基于JdbcTemplate自己封装了一套类MyBatis的Dao框架,视图层基于Velocity模板技术,其余组件基于SpringCloud全家桶. 问题1 某应用发布以后开始报数据库连接池不够用异常,日志如下: co

  • Spring源码分析容器启动流程

    目录 前言 源码解析 1.初始化流程 流程分析 核心代码剖析 2.刷新流程 流程分析 核心代码剖析 前言 本文基于 Spring 的 5.1.6.RELEASE 版本 Spring的启动流程可以归纳为三个步骤: 1.初始化Spring容器,注册内置的BeanPostProcessor的BeanDefinition到容器中 2.将配置类的BeanDefinition注册到容器中 3.调用refresh()方法刷新容器 Spring Framework 是 Java 语言中影响最为深远的框架之一,其

  • 源码分析系列之json_encode()如何转化一个对象

    json_encode()如何转化一个对象? 使用 json_encode() 将数组 array 转化成 json 字符串我们都已经很熟悉了 那么使用 json_encode() 转化一个对象是什么样的过程呢? 初步测试 我们需要新建一个具有多种属性的对象 新建 JsonTest class JsonTest { public const TEST = 'c'; public $a = 'a'; public static $b = 'b'; protected $e = 'e'; priva

  • 使用dynamic-datasource-spring-boot-starter实现多数据源及源码分析

    简介 前两篇博客介绍了用基本的方式做多数据源,可以应对一般的情况,但是遇到一些复杂的情况就需要扩展下功能了,比如:动态增减数据源.数据源分组,纯粹多库 读写分离 一主多从.从其他数据库或者配置中心读取数据源等等.其实就算没有这些需求,使用这个实现多数据源也比之前使用AbstractRoutingDataSource要便捷的多 dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器. github: https://g

  • JVM完全解读之Metaspace解密源码分析

    概述 metaspace,顾名思义,元数据空间,专门用来存元数据的,它是jdk8里特有的数据结构用来替代perm,这块空间很有自己的特点,前段时间公司这块的问题太多了,主要是因为升级了中间件所致,看到大家讨论来讨论去,看得出很多人对metaspace还是模棱两可,不是很了解它,因此我觉得有必要写篇文章来介绍一下它,解开它神秘的面纱,当我们再次碰到它的相关问题的时候不会再感到束手无策. 通过这篇文章,你将可以了解到 为什么会有metaspace metaspace的组成 metaspace的VM参

  • Netty分布式NioEventLoop任务队列执行源码分析

    目录 执行任务队列 跟进runAllTasks方法: 我们跟进fetchFromScheduledTaskQueue()方法 回到runAllTasks(long timeoutNanos)方法中 章节小结 前文传送门:NioEventLoop处理IO事件 执行任务队列 继续回到NioEventLoop的run()方法: protected void run() { for (;;) { try { switch (selectStrategy.calculateStrategy(selectN

随机推荐