spring boot文档阅读笔记——01
目录标题
- 一、日志
- (一)slf4j+ logback(spring boot默认方式)
- 1. 获取日志对象方式:
- 2. 设置日志级别:
- 3. 设置日志格式:
- 4. 输出到日志文件:
- 5. 日志文件设置:
- 6. 自定义日志配置文件:
- (二)slf4j + log4j2 (切换日志框架)
- log4j2 具体使用
- (三)json
- 1. Jackson 的使用
- 2. Fastjson
- (四)spring mvc
一、日志
Spring Boot 对所有内部使用共享资源日志记录 日志记录,但使基础日志实现保持打开状态。默认配置为 为 Java Util 提供 日志记录、log4J2 和 logback。在每种情况下,记录器都预先配置为使用控制台 还提供带有可选文件输出的输出。
注意:日志框架一般由日志门面和日志实现组成,日志门面相当于接口,日志实现相当于实现类。
- Spring-boot 默认使用: slf4j(门面) + logback(实现),已经集成到spring boot中,启动项目就能使用。
- 比较流行的日志框架: slf4j + log4j2,log4j2 性能较高。
(一)slf4j+ logback(spring boot默认方式)
spring boot 自身就是基于slf4j(门面) + logback(实现)的,这里说一下如何使用。
1. 获取日志对象方式:
- 通过日志工厂
package com.lihua.springboot;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootLogApplication {
static Logger logger = LoggerFactory.getLogger(SpringBootLogApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpringBootLogApplication.class, args);
logger.info("1111");
}
}
- 通过Lombok插件的@Slf4j 注解
package com.lihua.springboot;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Slf4j //注解会自动生成一个log对象
public class SpringBootLogApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootLogApplication.class, args);
log.info("1111");
}
}
2. 设置日志级别:
这些设置都是在 application.properties 中设置
# 日志配置
# 1. 日志级别
# logger.trace("跟踪");
# logger.debug("调试");
# logger.info("输出信息");
# logger.warn("警告");
# logger.error("异常");
# 设置全局 root是只根路径 ,默认info
logging.level.root = info
# 设置单个包 这里的com.lihua是包路径
#logging.level.com.lihua = trace
3. 设置日志格式:
# 2. 日志输出格式
# 默认格式 %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
logging.pattern.console = %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}
%clr(${LOG_LEVEL_PATTERN:-%5p})
%clr(${PID:- }){magenta}
%clr(---){faint}
%clr([%15.15t]){faint}
%clr(%-40.40logger{39}){cyan}
%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
//如果不需要哪个直接删除就好
- %clr(){faint} ——设置内容颜色
# 支持以下颜色和样式:
blue
cyan
faint
green
magenta
red
yellow
- %d等特殊符号理解
%5p 表示当前内容占多少字符(这里为5个) - ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS} 表示当LOG_DATEFORMAT_PATTERN 为null时取后面的内容,也就是-yyyy-MM-dd HH:mm:ss.SSS
4. 输出到日志文件:
logging:
file:
name: ./log/log.txt //指定文件名称和路径
path: ./log //指定目录,不能指定文件名(会默认为spring.log)
//注意两者不同时使用
5. 日志文件设置:
logging:
logback:
rollingpolicy:
max-file-size: 53KB //当日志数据大小超过指定值的时候,将日志压缩为一个压缩包,并清空日志文件内容
max-history: 7 //设置日志压缩文件保留时间
6. 自定义日志配置文件:
在项目的resources目录下创建一个【logback-spring.xml】日志配置文件,名称只要是以logback开头就行,测试使用log.xml并不会生成日志。
要配置logback-spring.xml,springboot会默认加载此文件,为什么不配置logback.xml,因为logback.xml会先application.properties加载,而logback-spring.xml会后于application.properties加载,这样我们在application.properties文中设置日志文件名称和文件路径才能生效。
一般的日志配置文件的组成有:properties(配置一些可以复用的常量)、appender(扩展、插件) 其实就是我们需要将日志输出到哪里,控制台、日志文件、http网络传输等 、root (使用插件)
比较简单的 logback-spring.xml :
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p ${PID:-} [%15.15t] %-30.30C{1.} : %m%n</pattern>-->
</encoder>
</appender>
<!--按天生成日志-->
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
poslog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
</FileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
</Pattern>
</layout>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="logFile"/>
</root>
</configuration>
进阶 logback-spring.xml :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="d:/logback"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 只会打印debug不会有info日志-->
<!-- <level>DEBUG</level>-->
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.example" level="debug"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>
(二)slf4j + log4j2 (切换日志框架)
将 spring boot自带的logback 依赖去掉。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
导入log4j2 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
注意:切换日志文件后,原来的logback的配置可能失效,比如日志格式。
默认的log4j2配置如下:
spring-boot-2.3.7.RELEASE.jar!\org\springframework\boot\logging\log4j2\log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
<Property name="CONSOLE_LOG_PATTERN">%clr{%d{${sys:LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${sys:LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
<Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
<Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
<Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
<Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
<Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
log4j2 官网
log4j2 具体使用
参考以前写的文章:Log4j2-study
一个详细的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,可设置一个非零的间隔秒数来检测配置变更 -->
<Configuration status="WARN" monitorInterval="60">
<!-- 自定义一些变量 -->
<Properties>
<!-- 变量定义 -->
<Property name="log_base_dir">/app_data/logs/my_app</Property>
<!-- Appender在将日志数据写入目标位置之前,一般会将日志数据通过Layout进行格式化。PatternLayout可以使用与C语言printf函数类似
的转换模式来指定输出格式。常见的配置如下:
- %d{yyyy-MM-dd HH:mm:ss.SSS} : 日志生成时间,输出格式为“年-月-日 时:分:秒.毫秒”
- %p : 日志输出格式
- %c : logger的名称
- %m : 日志内容,即 logger.info("message")
- %n : 换行符
- %T : 线程号
- %L : 日志输出所在行数
- %M : 日志输出所在方法名 -->
<Property name="log_pattern">[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5p][%T][%c.%M:%L] %msg%xEx%n</Property>
<!-- 单个日志文件最大大小,单位可以是KB, MB or GB -->
<Property name="max_single_file_size">1MB</Property>
</Properties>
<!-- 使用Appenders元素可以将日志事件数据写到各种目标位置(目前可以为控制台、文件、多种数据库API、远程套接字服务器、Apache Flume、
JMS、远程UNIX Syslog daemon),其内的每个Appender都必须要有一个name属性作为唯一标识,该标识的值在Logger中通过AppenderRef来引
用,从而将该Appender配置到该Logger中 -->
<Appenders>
<!-- Console Appender常用于将日志输出到System.out,一般用在开发环境 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 只接受程序中DEBUG级别的日志进行处理-->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 在大多数情况下,Appender将格式化LogEvent的责任委托给Layout -->
<PatternLayout pattern="${log_pattern}"/>
</Console>
<!-- RollingFile Appender会将日志输出到fileName属性指定的文件中,且需要指定TriggeringPolicy和RolloverStrategy。其中
TriggeringPolicy决定是否生成新的日志文件,RolloverStrategy决定如何生成新的日志文件。如果没有配置RolloverStrategy,则会
使用DefaultRolloverStrategy。从2.5开始,可以在DefaultRolloverStrategy中配置一个自定义的删除动作。从2.8开始,如果没有指定
文件名,则会使用DirectWriteRolloverStrategy来代替DefaultRolloverStrategy -->
<!-- 这个RollingFile Appender会打印出所有的DEBUG及以下级别(DEBUG、INFO、ERROR、FATAL、OFF)的信息 -->
<RollingFile name="DebugLogRollingFile" fileName="${log_base_dir}/my_app_debug.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_debug_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}" charset="UTF-8"/>
<!-- Policies表示一个CompositeTriggeringPolicy,可以组合多个TriggeringPolicy,只要内部的任意一个TriggeringPolicy
满足触发条件,都会滚动日志 -->
<Policies>
<!-- TimeBasedTriggeringPolicy用于按时间滚动日志。只要filePattern属性值中的日期/时间模式(pattern)不再应用于当
前文件时就进行日志滚动。这种规则通过interval和modulate属性来配置。interval属性指定一个整数,用于基于日期/时间模式中
的最小的时间单位数滚动一次。例如,filePattern值为/app_data/logs/my_app/$${date:yyyy_MM_dd}/my_app_%d{yyyy_
MM_dd_HH}_%i.log,这里使用小时作为最小的时间单位时,假如interval参数值为4,则表示每4小时滚动一次。默认值为1。
modulate表示是否调整interval属性值以便下次滚动发生在interval边界处。如果时间最小单位为小时,当前时间为早上3点,间隔
为4小时,则第一次滚动将发生在早上4点时(而不是早上7点),后续滚动将发生在早上8点、中午12点、下午4点等时刻 -->
<TimeBasedTriggeringPolicy interval="1" modulate="false"/>
<!-- SizeBasedTriggeringPolicy用于按文件大小滚动日志。每当日志文件超过size指定的大小(一般不超过几十MB,否则使用软
件打开导出的日志时很不方便),则这size大小的日志会自动存入按filePattern属性指定建立的文件夹下面并进行压缩存档 -->
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<!-- DefaultRolloverStrategy可以同时接受RollingFileAppender中filePattern属性值中日期/时间和整数计数器(%i)的
pattern,当日期/时间满足条件时,则会使用当前的日期/时间生成新的日志文件,如果filePattern属性值中含有一个整数计数器%i,则
在每次滚动时该整数都会增加,如果filePattern属性值中同时包含了日期/时间和整数计数器(%i),计数器会在日期/时间不变时而满足
其他滚动触发条件时(文件大小)开始自增,直到日期/时间发生变化时,计数器会重新自增。以.gz、.zip、.bz2、deflate、pack200
或xz结尾的filePattern值,会在日志文件归档时以后缀对应的格式进行压缩。min属性指定计数器的最小值,默认为1。max属性指定计数
器的最大值,一旦计数器达到了最大值,最早的归档将会在每次滚动时被删除,默认值为7。fileIndex属性如果设置为max(默认),则具
有更大索引的文件比具有更小索引的文件内容更新,如果设置为min,文件将重命名且计数器将遵循Fixed Window策略,这两种情况均有可
能导致批量的文件重命名,自2.8版本开始,如果fileIndex属性设置为nomax,则min和max属性值都将会被忽略,文件编号将每次递增1,
每次滚动都会递增到更大的值,且没有最大文件编号的限制 -->
<!--<DefaultRolloverStrategy max="100" min="1" fileIndex = "nomax"/>-->
<DefaultRolloverStrategy fileIndex="nomax">
<!-- Log4j 2.5引入了删除动作(Delete元素)。在滚动删除旧的日志文件时,相比使用DefaultRolloverStrategy的max属
性,该功能可以让用户拥有更多的删除控制。删除动作可以让用户配置若干个条件来删除相对于基准目录的文件。该功能可以删除非日
志文件,使用时一定要小心。可以通过testMode属性来测试配置是否会错删文件。basePath属性值用于指定删除文件的基准目录,必
须显式指定。maxDepth属性指定扫描目录的最大层级,0表示仅能访问基准目录(安全限制不能访问的情况除外),
Integer.MAX_VALUE值表示可以访问所有层级。默认值为1,表示仅扫描基准目录下的文件。testMode属性值如果设置为true,文件
不会实际删除,而是在status logger打印一条INFO级别的消息,可以使用该功能来测试是否会错删目标文件,默认为false。-->
<!-- 这里的Delete元素配置了每次滚动都会删除基准目录下匹配“*/my_app_debug_*.log.gz”日志文件,只要9分钟以前的日志文
件总大小超过2MB,或9分钟以前的日志文件文件总数超过2个就按时间顺序删除较早的日志文件。该元素可以防止日志文件所在分区的
磁盘空间被占满。特别需要注意的是,只有在发生日志滚动时才会尝试进行删除,否则即使满足了删除条件,但如果没有新的滚动日志
生成的话也不会发生删除操作。 -->
<Delete basePath="${log_base_dir}" maxDepth="2">
<!-- Delete元素里可以指定若干个PathCondition类型的元素。如果指定了不止一个条件,则这些条件都需要在删除之前接受
某个路径。这些条件可以嵌套,只有外部条件接受某个路径之后,其内部条件才会决定是否接受该路径。如果这些条件没有嵌套,
则它们的执行顺序是任意的。这些条件也可以通过使用IfAll, IfAny和IfNot等组合条件进行AND、OR和NOT等逻辑运算。用户
也可以创建自定义条件或使用内置条件:
- IfFileName:接受匹配正则表达式或glob的文件路径;
- IfLastModified:接受比指定时段早或一样早的文件;
- IfAccumulatedFileCount:在遍历文件树时文件总数超过文件数上限后接受路径;
- IfAccumulatedFileSize:在遍历文件树时文件总大小超过上限后接受路径;
- IfAll:如果所有内嵌条件都接受了某个路径才会接受该路径,相当于AND逻辑,其内嵌条件的执行顺序是任意的;
- IfAny:如果任意一个内嵌条件接受了某个目录就接受该目录,相当于OR逻辑,其内嵌条件的执行顺序是任意的;
- IfNot:如果内嵌条件不接受某个路径就接收该路径,相当于NOT逻辑。-->
<!-- IfFileName可以通过glob(使用受限的模式语言,比正则更简单)或regex属性(正则)来匹配相对路径(相对于Delete
的basePath属性指定的基准目录)-->
<!-- 当外部的条件满足时才会计算内部的条件,内部的同级条件的计算顺序是任意的。 -->
<IfFileName glob="*/my_app_debug_*.log.gz">
<!-- IfLastModified可以通过age属性值来指定接受最后修改时间为指定时间或早于指定时间的路径,该属性的值可参考
org.apache.logging.log4j.core.appender.rolling.action.Duration.parse(CharSequence text)方法的文档 -->
<!-- 这里的IfLastModified指定删除达到或超过60天内的文件 -->
<IfLastModified age="9m">
<!-- 这里的IfAny内嵌了两个PathCondition,表示满足任意一个条件即可 -->
<IfAny>
<!-- IfAccumulatedFileSize可通过exceeds属性值指定一个文件总大小上限值。如果文件数超过了该上限值
则删除文件 -->
<IfAccumulatedFileSize exceeds="2MB"/>
<!-- IfAccumulatedFileCount可通过exceeds属性值指定一个文件总数上限值。如果文件数超过了该上限值
则删除文件 -->
<IfAccumulatedFileCount exceeds="2"/>
</IfAny>
</IfLastModified>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="InfoLogRollingFile" fileName="${log_base_dir}/my_app_info.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_info_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<DefaultRolloverStrategy fileIndex="nomax">
<Delete basePath="${log_base_dir}" maxDepth="2">
<IfFileName glob="*/my_app_info_*.log.gz">
<!-- 这里表示匹配“*/my_app_info_*.log.gz”模式的日志文件的删除策略如下:
- 只要日志文件总数量超过5个就删除按时间顺序最早的日志文件
- 只要日志文件总大小超过10MB就会删除按时间顺序最早的日志文件
- 只要日志文件最近修改时间为9分钟前或更早就会删除按时间顺序最早的日志文件 -->
<IfAny>
<IfAccumulatedFileSize exceeds="8MB"/>
<IfAccumulatedFileCount exceeds="5"/>
<IfLastModified age="9m"/>
</IfAny>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="WarnLogRollingFile" fileName="${log_base_dir}/my_app_warn.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_warn_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<DefaultRolloverStrategy fileIndex="nomax">
<Delete basePath="${log_base_dir}" maxDepth="2">
<IfFileName glob="*/my_app_warn_*.log.gz">
<IfAny>
<IfAccumulatedFileSize exceeds="3GB"/>
<IfAccumulatedFileCount exceeds="3000"/>
<IfLastModified age="30d"/>
</IfAny>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="ErrorLogRollingFile" fileName="${log_base_dir}/my_app_error.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_error_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<DefaultRolloverStrategy fileIndex="nomax">
<Delete basePath="${log_base_dir}" maxDepth="2">
<IfFileName glob="*/my_app_error_*.log.gz">
<IfAny>
<IfAccumulatedFileSize exceeds="3GB"/>
<IfAccumulatedFileCount exceeds="3000"/>
<IfLastModified age="30d"/>
</IfAny>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- 记录druid的SQL语句 -->
<RollingFile name="DruidSqlRollingFile" fileName="${log_base_dir}/druid.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/druid_%d{yyyy_MM_dd_HH}_%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<DefaultRolloverStrategy fileIndex="nomax">
<Delete basePath="${log_base_dir}" maxDepth="2" testMode="true">
<IfFileName glob="*/druid_*.log.gz">
<IfAny>
<IfAccumulatedFileSize exceeds="3GB"/>
<IfAccumulatedFileCount exceeds="3000"/>
<IfLastModified age="30d"/>
</IfAny>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
<Loggers>
<!-- 当Logger在配置文件中声明时,就创建了一个LoggerConfig对象,两者一一对应,LoggerConfig包含一些Filter、这些
Filters用于过滤传递给任意Appender的LogEvent,它还包含一些Appender的引用。Logger本身执行无指向的动作,它仅含有一
个与LoggerConfig关联的名称(通过name属性指定),root Logger具有固定的默认名称,其他Logger需要指定各自的name属性
值。LoggerConfig会被分配一个日志级别,通过level属性来指定。内建的日志级别按优先级从高到底排序有:OFF > FATAL >
ERROR > WARN > INFO > DEBUG > TRACE > ALL,Log4j 2 也支持自定义的日志级别。
-->
<Root level="ALL">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLogRollingFile"/>
<AppenderRef ref="WarnLogRollingFile"/>
<AppenderRef ref="DebugLogRollingFile"/>
<AppenderRef ref="ErrorLogRollingFile"/>
</Root>
<!-- 每个LoggerConfig的日志级别如果没有显式配置,则会继承其父级LoggerConfig的日志级别,而root LoggerConfig如果没
有配置日志级别,则会为其分配一个默认的ERROR级别 -->
<!-- 某个Logger所允许的每条日志打印请求都会传递给其LoggerConfig中的所有Appender,也会传递给该LoggerConfig的parent
LoggerConfig中的Appender,这种现象称为相加性(Additivity)。也就是说,Appender会从LoggerConfig的继承中继承相加性。这种特
性可以用来汇整某几个logger的输出,可以在声明Logger的配置文件中设置additivity="false"来禁用这种叠加继承 -->
<!--记录druid-sql的记录-->
<Logger name="druid.sql.Statement" level="debug" additivity="false">
<appender-ref ref="DruidSqlRollingFile"/>
</Logger>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.mybatis" level="INFO"/>
<!--log4j2 自带过滤日志-->
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error"/>
<Logger name="org.apache.catalina.util.LifecycleBase" level="error"/>
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn"/>
<Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn"/>
<Logger name="org.crsh.plugin" level="warn"/>
<Logger name="org.crsh.ssh" level="warn"/>
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error"/>
<Logger name="org.hibernate.validator.internal.util.Version" level="warn"/>
<Logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
<Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<Logger name="org.thymeleaf" level="warn"/>
</Loggers>
</Configuration>
(三)json
市面比较常用的json框架有三种,Gson、Jackson、FastJson
- Gson
项目地址:https://github.com/google/gson
Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。 Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。 在使用这种对象转换之前,需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。 类里面只要有get和set方法,Gson完全可以实现复杂类型的json到bean或bean到json的转换,是JSON解析的神器。
- FastJson
项目地址:https://github.com/alibaba/fastjson
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。 FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。 FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
- Jackson
项目地址:https://github.com/FasterXML/jackson
Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson社区相对比较活跃,更新速度也比较快, 从Github中的统计来看,Jackson是最流行的json解析器之一,Spring MVC的默认json解析器便是Jackson
。
Jackson优点很多:
Jackson 所依赖的jar包较少,简单易用。
与其他 Java 的 json 的框架 Gson 等相比,Jackson 解析大的 json 文件速度比较快。
Jackson 运行时占用内存比较低,性能比较好
Jackson 有灵活的 API,可以很容易进行扩展和定制。
目前最新版本是2.9.4,Jackson 的核心模块由三部分组成:
jackson-core 核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
jackson-annotations 注解包,提供标准注解功能;
jackson-databind 数据绑定包,提供基于”对象绑定” 解析的相关 API( ObjectMapper )和”树模型” 解析的相关 API(JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API。
1. Jackson 的使用
spring boot 项目自带了Jackson ,无需导入。
ObjectMapper 是 Jackson 库中最常用的一个类,使用它可以进行 Java 对象和 JSON 字符串之间快速转换。如果你用过 FastJson,那么 Jackson 中的 ObjectMapper 就如同 FastJson 中的 JSON 类。
- 将java对象序列化(格式化)为json
ObjectMapper mapper = new ObjectMapper();
User user = new User(1,"lihua",18);
try {
String s = mapper.writeValueAsString(user);
log.info(s);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
-
- 将json反序列化(解析)为java对象
ObjectMapper mapper = new ObjectMapper();
User user = new User(1,"lihua",18);
try {
String s = mapper.writeValueAsString(user);
log.info(s);
//反序列化
User user1 = mapper.readValue(s, User.class);
log.info(user1.toString());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
注意:需要序列化和反序列化的对象的类需要提供set、get方法。
jackson 支持弱匹配,如果在解析json时,目标对象有些属性不存在,那么不匹配它,或者json中有多余的字段,也忽略。objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- 完整代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Family {
private String name;
private int num;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private int id;
private String name;
private int age;
private Family family;
}
@RestController
@Slf4j
public class ControllerTest {
@RequestMapping("/hello")
public String test(){
ObjectMapper mapper = new ObjectMapper();
User user = new User(1,"lihua",18,new Family("li",5));
try {
String s = mapper.writeValueAsString(user);
log.info(s);
User user1 = mapper.readValue(s, User.class);
//将json串转换成 json节点,通过get方法可以获取节点里面的子节点。
JsonNode jsonNode = mapper.readTree(s);
System.out.println(jsonNode.toString());
JsonNode family = jsonNode.get("family");
System.out.println(family);
log.info(user1.toString());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return "hello";
}
}
更多,推荐阅读Springboot Jackson 解析 JSON 详细教程
jackson 常用配置
# 日期格式字符串或标准日期格式类全限定名,只控制java.util.Date的序列化format
spring.jackson.date-format= yyyy-MM-dd HH:mm:ss
# 指定Joda date/time的格式,比如yyyy-MM-ddHH:mm:ss. 如果没有配置的话,dateformat会作为backup。
spring.jackson.joda-date-time-format= yyyy-MM-dd HH:mm:ss
# 全局设置pojo或被@JsonInclude注解的属性的序列化方式
spring.jackson.default-property-inclusion= NON_NULL
# 不为空的属性才会序列化,具体属性可看JsonInclude.Include
# 是否开启Jackson的序列化
# 示例:spring.jackson.serialization.indent-output= true
spring.jackson.serialization.*=
# 是否开启Jackson的反序列化
spring.jackson.deserialization.*=
# 是否开启json的generators
# 示例:spring.jackson.generator.auto-close-json-content=true
spring.jackson.generator.*=
# 指定json使用的Locale
spring.jackson.locale= zh
# 是否开启Jackson通用的特性
spring.jackson.mapper.*=
# 是否开启jackson的parser特性
spring.jackson.parser.*=
# 指定Json策略模式
spring.jackson.property-naming-strategy=com.fasterxml.jackson.databind.PropertyNamingStrategy.UpperCamelCaseStrategy
# 或
spring.jackson.property-naming-strategy=UPPER_CAMEL_CASE
# 是否开启Jackson的反序列化
spring.jackson.serialization.*=
# 指定日期格式化时区,比如America/Los_Angeles或者GMT+10
spring.jackson.time-zone= GMT+8
2. Fastjson
个人觉得Fastjson的使用门槛比较低,方法命名也符合中国人的理解。
- maven坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
@RequestMapping("/hello1")
public String test1(){
User user = new User(1,"lihua",18,new Family("li",5));
//序列化
String s = JSON.toJSONString(user);
log.info(s);
//反序列化
User user1 = JSON.parseObject(s, User.class);
log.info(user1.toString());
return "hello";
}
(四)spring mvc
官方文档:spring mvc
spring mvc文档阅读笔记
spring boot文档上的内容,很全但是不细,都是提了一嘴,没有将具体如何使用。。。。。暂时不更新了。