MDC(Mapped Diagnostic Context)是 SLF4J 和 log4j 等日志框架提供的一种方案,它允许开发者将一些特定的数据(如用户ID、请求ID等)存储到当前线程的上下文中,使得这些数据可以在日志消息中使用。这对于跟踪多线程或高并发应用中的单个请求非常有用。
在高并发环境中,由于多个请求可能同时处理,日志消息可能会交错在一起。使用MDC,我们可以为每个请求分配一个唯一的标识,并将该标识添加到每条日志消息中,从而方便地区分和跟踪每个请求的日志。
在 Log4j 或 Logback 的配置文件中,可以配置日志格式,以便输出 MDC 中的键值对。例如,在 Log4j2 的 log4j2.xml 配置文件中:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %X{mdcKey} - %msg%n"/>
在 Logback 的 logback.xml 配置文件中:
<!-- 其他内容... -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d 表示日期,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度 %errorMessage:日志消息,%n 是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %X{mdcKey} - %msg%n</pattern>
</encoder>
在上面的配置中,%X{mdcKey} 是一个占位符,用于输出 MDC 中键为 mdcKey 的值。
在代码中,可以在适当的位置(比如请求的开始处)设置 MDC 的值,在请求结束时清除这些值。
java
复制
MDC 的内容是保存在线程局部变量中的,因此它对子线程是不继承的。如果需要在子线程中使用父线程的 MDC 数据,需要手动复制。
使用 MDC 时,确保在所有可能的执行路径上都调用了 MDC.clear(),以避免内存泄漏。
JSR 380 提供了一系列校验注解,可以用于各种数据校验场景。以下是一个全面的列表,包括了一些常用的校验注解及其简要说明:
@AssertTrue: 验证 Boolean 对象是否为 true。
@AssertFalse: 验证 Boolean 对象是否为 false。
@Min(value): 验证 Number 对象是否大于或等于指定的最小值。
@Max(value): 验证 Number 对象是否小于或等于指定的最大值。
@DecimalMin(value): 验证 Number 对象是否大于或等于指定的最小值(可以是小数)。
@DecimalMax(value): 验证 Number 对象是否小于或等于指定的最大值(可以是小数)。
@Size(min=, max=): 验证集合、数组或字符串的大小是否在指定的范围内。
@Digits(integer=, fraction=): 验证 Number 对象是否是一个整数或小数,并且整数部分和小数部分的位数分别不超过指定的值。
@Future: 验证日期对象是否在当前时间之后。
@Pattern(regex=, flags=): 验证字符串是否匹配指定的正则表达式。
Bean Validation 2.0 新增注解
@Email: 验证字符串是否是一个有效的电子邮件地址。
@NotEmpty: 验证集合、数组或字符串是否不为 null 且不为空。
@NotBlank: 验证字符串是否不为 null 且去除前后空格后长度不为 0。
@Positive: 验证 Number 对象是否为正数。
@PositiveOrZero: 验证 Number 对象是否为正数或零。
@Negative: 验证 Number 对象是否为负数。
@NegativeOrZero: 验证 Number 对象是否为负数或零。
@GroupSequenceProvider: 动态定义校验组序列。
@ReportAsSingleViolation: 当一个字段上有多个约束时,将它们报告为一个单一的违规。
Hibernate Validator 扩展
除了 JSR 380 标准注解,Hibernate Validator 还提供了一些额外的校验注解:
@Length: 验证字符串的长度是否在指定的范围内。
@CreditCardNumber: 验证字符串是否是一个有效的信用卡号码。
@ISBN: 验证字符串是否是一个有效的 ISBN。
@SafeHtml: 验证字符串是否是安全的 HTML。
@ScriptAssert: 允许在注解中使用脚本表达式进行校验。 这些注解可以在实体类的字段、方法或构造器上使用,以实现各种数据校验需求。在使用时,需要确保你的项目中包含了相应的校验器实现,如 Hibernate Validator。
在Springboot中使用JSR380
在 Spring Boot 中使用 JSR 380 参数校验非常简单,因为 Spring Boot 自动配置了 Bean Validation。以下是如何在 Spring Boot 应用程序中使用 JSR 380 参数校验的步骤:
确保你的 pom.xml 或 build.gradle 文件中包含以下依赖项: 对于 Maven:
对于 Gradle:
在你的实体类上使用 JSR 380 校验注解来定义校验规则:
在控制器的方法参数上使用 @Valid 注解来触发校验:
Spring Boot 会自动处理校验异常,你可以使用 @ControllerAdvice 和 @ExceptionHandler 来全局处理校验异常:
这里的 ApiError 是一个自定义的错误响应类,你可以根据需要自行定义。 通过以上步骤,你就可以在 Spring Boot 应用程序中全面使用 JSR 380 参数校验了。记得在出现校验错误时,Spring Boot 会返回一个 400 Bad Request 响应。
在 logback-weblog.xml 配置文件中,要引用ApiOperationLogAspect 日志切面类 doAround() 方法中请求的跟踪标识traceId,需要这样配置pattern:
完整配置如下:
将Web环境换为生产环境prod后,重新请求测试api,得到文件中日志格式已改变:
按照添加依赖的说明,在 weblog-web 模块中的 pom.xml 文件添加参数校验依赖:
使用注解
在controller层测试请求函数中添加捕获,将错误信息返回
测试入参正确和不正确的情况下的返回值:
参数:
结果:
参数:
结果: