spring boot文档阅读笔记——02

news2024/11/13 9:43:58

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. 获取日志对象方式:

  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");
    }

}

  1. 通过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

  1. 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解析的神器。

  1. FastJson

项目地址:https://github.com/alibaba/fastjson

Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。 FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。 FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。

  1. 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的使用门槛比较低,方法命名也符合中国人的理解。

  1. 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文档上的内容,很全但是不细,都是提了一嘴,没有将具体如何使用。。。。。暂时不更新了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于python的mediapipe库踩过的坑

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

Nginx 常用配置汇总!

众所周知&#xff0c;Nginx 是 Apache服务不错的替代品。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上 Nginx 的并发能力在同类型的网页服务器中表现较好&#xff0c;因此国内知名大厂例如&#xff1a;淘宝&#xff0c;京东&#xff0c;百度&#xff0c;新浪&a…

1.10 golang 切片Slice

1. 切片Slice 需要说明&#xff0c;slice 并不是数组或数组指针。它通过内部指针和相关属性引用数组片段&#xff0c;以实现变长方案。 1. 切片&#xff1a;切片是数组的一个引用&#xff0c;因此切片是引用类型。但自身是结构体&#xff0c;值拷贝传递。2. 切片的长度可以改变…

零基础机器学习做游戏辅助第六课--猫狗数据集认识卷积神经网络(二)

一、初识卷积 上一课我们已经将图像数据进行了预处理,这节课的重点就是学习卷积神经网络,到底什么是卷积,我们看图 input是我们输入的图像,Kernel是我们设置的3x3卷积核,卷积层将图像和卷积核进行计算提取特征输出神经元。

代码随想录算法训练营第35天 回溯算法 java :455.分发饼干 376. 摆动序列53. 最大子序和

文章目录贪心算法思路LeetCode 455.分发饼干题目详解LeetCode 376. 摆动序列题目详解思路示图LeetCode 53. 最大子序和题目详解思路示图总结贪心算法思路 以局部最优带动全局最优 LeetCode 455.分发饼干 题目详解 我做的是采用 优先满足胃口的思路。 对每个孩子 i&#xff…

【c#系列】PDF进行操作-浏览、分割、合并、插入、删除(2)

这节我们主要实现缩小、旋转、打印、分割、合并、放大等功能 1、 放大功能 单击放大按钮&#xff0c;实现PDF放大预览&#xff0c;效果如下&#xff1a; 设计代码&#xff1a; System.Windows.Forms.ToolStripButton FangDaBT_Tool;FangDaBT_Tool new System.Windows.Form…

GBase GCDW云数仓阿里云版免费试用来了!

GBase GCDW云原生数据仓库&#xff08;GCDW&#xff09;在阿里云计算巢上提供免费试用了&#xff01;简单 3 步&#xff0c;即可获得一个免费试用的GCDW服务实例&#xff0c;您可以定制该服务实例的云主机规格和数据库计算服务节点数等实例参数&#xff0c;该免费试用支持的数据…

LabVIEW NI CompactRIO控制器:性能和吞吐量基准测试

LabVIEW NI CompactRIO控制器&#xff1a;性能和吞吐量基准测试CompactRIO控制器基于LabVIEW RIO架构&#xff0c;采用了功能强大的64位Intel Atom E3800片上系统(SoC)和Xilinx Kintex7 FPGA等最新技术。Intel Atom SoC提供了极高的性能和丰富的功能&#xff0c;包括集成式GPU和…

数据结构实验二 :二叉树的操作与实现

数据结构实验一:线性表,堆栈和队列实现 数据结构实验二 :二叉树的操作与实现 数据结构实验三: 图的操作与实现 数据结构实验四 : 查找和排序算法实现 文章目录一、实验目的&#xff1a;二、使用仪器、器材三、实验内容及原理1、教材P247实验题1&#xff1a;实现二叉树的各种基本…

Mybatis 笔记

一、mybatis简介 1.1 框架概念 软件的半成品&#xff0c;完成软件开发过程中的通用操作&#xff0c;实现特定的功能&#xff0c;从而简化开发人员在软件开发中的步骤&#xff0c;提升开发效率。 1.2 常用框架 MVC框架&#xff1a;简化servlet的开发步骤&#xff0c;与前端交…

java实现oracle和mysql的group by分组功能|同时具备max()/min()/sum()/case when 函数等功能

一、前言oracle和mysql的group by 分组功能大家应该清楚&#xff0c;那如何使用java实现同样的功能呢比如下面这个表idnameagemathEnglish10yujianlin2092.5103ww84102520102611036310351020我们需要按id分组&#xff0c;求最大age和math累计成绩我们的sql应该这样写select id,…

Linux下的安装环境

目录 软件安装常识 Linux软件安装生态 Linux软件生态的本土化 yum的三板斧&#xff1a;查找、安装、卸载 yum补充的3个小知识 软件安装常识 我们知道Linux下有一条命令可以下载安装指令&#xff0c;那就是yum。在了解yum之前得先说一下Linux的整体安装环境。 Linux下用y…

每日学术速递2.1

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.Cv 1.SeaFormer: Squeeze-enhanced Axial Transformer for Mobile Semantic Segmentation 标题&#xff1a;SeaFormer:用于移动语义分割的挤压增强型轴向变换器 作者&#xff1a; Qian…

从 await-to-js 到 try-run-js

之前在做 code review 时候发现有同事使用 try catch 包装了一堆异步代码&#xff0c;于是个人就觉得很奇怪&#xff0c;难道不应该只 catch 可能出问题的代码吗&#xff1f;同事告诉我说 try catch 太细的话会出现内外作用域不一致&#xff0c;需要提前声明变量。 let res: D…

【微服务】微服务保护Sentinel

微服务保护Sentinel1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel1.4.微服务整合Sentinel2.流量控制2.1.簇点链路2.1.快…

豆瓣引流流程

豆瓣引流注册账号养号如何把豆瓣的帖子打造好并且引流到微信注册账号 第一&#xff1a;可以去营业厅或者卡商那里购买一批卡来进行注册。 第二&#xff1a;可以通过接码平台进行大量的一个小号注册&#xff0c;我们注册的号前期是作为一个顶帖号来使用。 第三&#xff1a;我…

商业智能 BI 跟业务系统的思维差异

我们在跟企业的沟通过程中经常发现&#xff0c;很多企业还是分不清商业智能 BI 跟一般的业务信息化系统定位、用户、思维层面上的差异。因为在企业的IT信息化规划中&#xff0c;基础的业务系统建设一定是走在前面的&#xff0c;有了这些系统基础&#xff0c;才会有数据的积累&a…

Python绘制图片一

文章目录一、代码段讲解1. theta np.linspace(0.0, 2 * np.pi, N , endpointFalse)2. ax plt.subplot(111,projectionpolar)3. bar.set_facecolor(plt.cm.viridis(r / 10.))4. bar.set_alpha(0.5)二、附录一、代码段讲解 1. theta np.linspace(0.0, 2 * np.pi, N , endpoint…

Windows软件:如何使用VMware® Workstation 16 Pro安装Centos7操作系统

前言&#xff1a; 在我们开发Java项目当中&#xff0c;经常会将jar包部署在Linux操作系统中运行&#xff0c;其中Centos7使用最广泛&#xff0c;前后端的各种运行环境所必须的软件均在此上运行&#xff0c;本章我们就来讲一下如何使用VMware安装Centos7系统&#xff0c;以便我们…

08技术太卷我学APEX-页面上显示静态图片

08技术太卷我学APEX-页面上显示静态图片 0 我想在首页面上留个人微信二维码和微信群二维码 我想在《技术太卷我学APEX》首页上留下联系方式&#xff0c;方便同学们加群一起交流联系方式。 先手机登录个人微信&#xff0c;截图个人微信二维码和《技术太卷我学APEX》微信群二维…