1、修改包名,避免自动配置被SpringBoot隐性优先规则覆盖
Sync All Branches to GitHub / sync (push) Successful in 3s

2、自定义Jackson starter
This commit is contained in:
hanfuye
2026-01-12 16:28:31 +08:00
parent 5c18560351
commit 4eb71c4d4d
33 changed files with 407 additions and 326 deletions
+8 -4
View File
@@ -4,9 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.crushtj</groupId>
<artifactId>xiaoyishu</artifactId>
<version>${revision}</version>
<groupId>com.jy</groupId>
<artifactId>xiaoyishu</artifactId>
<version>${revision}</version>
</parent>
<packaging>pom</packaging>
@@ -15,9 +15,13 @@
<name>${project.artifactId}</name>
<description>平台基础设施层:封装一些常用功能,供各个业务线拿来即用</description>
<modules>
<modules>
<!--通用-->
<module>xiaoyi-common</module>
<!--日志切面-->
<module>xiaoyi-spring-boot-starter-biz-operationlog</module>
<!--Jackson-->
<module>xiaoyi-spring-boot-starter-jackson</module>
</modules>
</project>
+7 -1
View File
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.crushtj</groupId>
<groupId>com.jy</groupId>
<artifactId>xiaoyi-framework</artifactId>
<version>${revision}</version>
</parent>
@@ -36,6 +36,12 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- AOP 切面 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,12 +1,12 @@
package top.crushtj.framework.common.constant;
package com.jy.framework.common.constant;
import java.time.format.DateTimeFormatter;
/**
* @Title: DateConstants
* @Description: 日期常量
* @Author: ayi
* @Date: 2025/11/26
* @author ayi
* @title DateConstants
* @description 日期常量
* @date 2025/11/26
*/
public interface DateConstants {
/**
@@ -27,5 +27,5 @@ public interface DateConstants {
/**
* DateTimeFormatter-
*/
DateTimeFormatter DATE_FORMAT_Y_M = DateTimeFormatter.ofPattern("yyyy-MM");
DateTimeFormatter DATE_FORMAT_Y_M = DateTimeFormatter.ofPattern("yyyy-MM");
}
@@ -0,0 +1,26 @@
package com.jy.framework.common.exception;
/**
*
* @author ayi
* @title BaseExceptionInterface
* @description 基础异常接口
* @date 2025/11/20
*/
public interface BaseExceptionInterface {
/**
* 获取异常码
*
* @return 异常码
*/
String getCode();
/**
* 获取异常信息
*
* @return 异常信息
*/
String getMessage();
}
@@ -0,0 +1,38 @@
package com.jy.framework.common.exception;
import lombok.Getter;
import lombok.Setter;
/**
*
* @author ayi
* @title BusiException
* @description 业务异常
* @date 2025/11/20
*/
@Getter
@Setter
public class BizException extends RuntimeException {
/**
* 异常码
*/
private String code;
/**
* 异常信息
*/
private String message;
/**
* 构造函数
*
* @param baseExceptionInterface 基础异常接口
*/
public BizException(BaseExceptionInterface baseExceptionInterface) {
this.code = baseExceptionInterface.getCode();
this.message = baseExceptionInterface.getMessage();
}
}
@@ -0,0 +1,132 @@
package com.jy.framework.common.response;
import java.io.Serial;
import java.io.Serializable;
import lombok.Data;
import com.jy.framework.common.exception.BaseExceptionInterface;
import com.jy.framework.common.exception.BizException;
/**
*
* @author ayi
* @title Response
* @description 响应体
* @date 2025/11/20
*/
@Data
public class Response<T> implements Serializable {
@Serial
private static final long serialVersionUID = -6624218097474846897L;
/**
* 响应码
*/
private String code;
/**
* 响应信息
*/
private String message;
/**
* 是否成功
*/
private boolean success = true;
/**
* 响应数据
*/
private T data;
/**
* 成功响应
*
* @return 成功响应
*/
public static <T> Response<T> success() {
return new Response<>();
}
/**
* 成功响应
*
* @param data 响应数据
* @return 成功响应
*/
public static <T> Response<T> success(T data) {
Response<T> response = new Response<>();
response.setData(data);
return response;
}
/**
* 失败响应
*
* @return 失败响应
*/
public static <T> Response<T> failure() {
Response<T> response = new Response<>();
response.setSuccess(false);
return response;
}
/**
* 失败响应
*
* @param message 异常信息
* @return 失败响应
*/
public static <T> Response<T> failure(String message) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setMessage(message);
return response;
}
/**
* 失败响应
*
* @param code 异常码
* @param message 异常信息
* @return 失败响应
*/
public static <T> Response<T> failure(String code, String message) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(code);
response.setMessage(message);
return response;
}
/**
* 失败响应
*
* @param bizException 业务异常
* @return 失败响应
*/
public static <T> Response<T> failure(BizException bizException) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(bizException.getCode());
response.setMessage(bizException.getMessage());
return response;
}
/**
* 失败响应
*
* @param <T> 响应数据类型
* @param baseExceptionInterface 基础异常
* @return 失败响应
*/
public static <T> Response<T> failure(BaseExceptionInterface baseExceptionInterface) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(baseExceptionInterface.getCode());
response.setMessage(baseExceptionInterface.getMessage());
return response;
}
}
@@ -1,4 +1,4 @@
package top.crushtj.framework.common.utils;
package com.jy.framework.common.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -8,10 +8,10 @@ import lombok.SneakyThrows;
/**
*
* @Title: JsonUtils
* @Description: JSON 工具类
* @Author: ayi
* @Date: 2025/11/21
* @author ayi
* @title JsonUtils
* @description JSON 工具类
* @date 2025/11/21
*/
public class JsonUtils {
private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@@ -1,26 +0,0 @@
package top.crushtj.framework.common.exception;
/**
*
* @Title: BaseExceptionInterface
* @Description: 基础异常接口
* @Author: ayi
* @Date: 2025/11/20
*/
public interface BaseExceptionInterface {
/**
* 获取异常码
*
* @return 异常码
*/
String getCode();
/**
* 获取异常信息
*
* @return 异常信息
*/
String getMessage();
}
@@ -1,38 +0,0 @@
package top.crushtj.framework.common.exception;
import lombok.Getter;
import lombok.Setter;
/**
*
* @Title: BusiException
* @Description: 业务异常
* @Author: ayi
* @Date: 2025/11/20
*/
@Getter
@Setter
public class BizException extends RuntimeException {
/**
* 异常码
*/
private String code;
/**
* 异常信息
*/
private String message;
/**
* 构造函数
*
* @param baseExceptionInterface 基础异常接口
*/
public BizException(BaseExceptionInterface baseExceptionInterface) {
this.code = baseExceptionInterface.getCode();
this.message = baseExceptionInterface.getMessage();
}
}
@@ -1,131 +0,0 @@
package top.crushtj.framework.common.response;
import java.io.Serializable;
import lombok.Data;
import top.crushtj.framework.common.exception.BaseExceptionInterface;
import top.crushtj.framework.common.exception.BizException;
/**
*
* @Title: Response
* @Description: 响应体
* @Author: ayi
* @Date: 2025/11/20
*/
@Data
public class Response<T> implements Serializable {
private static final long serialVersionUID = -6624218097474846897L;
/**
* 响应码
*/
private String code;
/**
* 响应信息
*/
private String message;
/**
* 是否成功
*/
private boolean success = true;
/**
* 响应数据
*/
private T data;
/**
* 成功响应
*
* @return 成功响应
*/
public static <T> Response<T> success() {
return new Response<>();
}
/**
* 成功响应
*
* @param data 响应数据
* @return 成功响应
*/
public static <T> Response<T> success(T data) {
Response<T> response = new Response<>();
response.setData(data);
return response;
}
/**
* 失败响应
*
* @return 失败响应
*/
public static <T> Response<T> failure() {
Response<T> response = new Response<>();
response.setSuccess(false);
return response;
}
/**
* 失败响应
*
* @param message 异常信息
* @return 失败响应
*/
public static <T> Response<T> failure(String message) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setMessage(message);
return response;
}
/**
* 失败响应
*
* @param code 异常码
* @param message 异常信息
* @return 失败响应
*/
public static <T> Response<T> failure(String code, String message) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(code);
response.setMessage(message);
return response;
}
/**
* 失败响应
*
* @param bizException 业务异常
* @return 失败响应
*/
public static <T> Response<T> failure(BizException bizException) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(bizException.getCode());
response.setMessage(bizException.getMessage());
return response;
}
/**
* 失败响应
*
* @param <T>
* @param baseExceptionInterface 基础异常
* @return 失败响应
*/
public static <T> Response<T> failure(BaseExceptionInterface baseExceptionInterface) {
Response<T> response = new Response<>();
response.setSuccess(false);
response.setCode(baseExceptionInterface.getCode());
response.setMessage(baseExceptionInterface.getMessage());
return response;
}
}
@@ -4,25 +4,23 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.crushtj</groupId>
<groupId>com.jy</groupId>
<artifactId>xiaoyi-framework</artifactId>
<version>${revision}</version>
</parent>
<packaging>jar</packaging>
<artifactId>xiaoyi-spring-boot-starter-biz-operationlog</artifactId>
<name>${project.artifactId}</name>
<description>平台基础设施层:操作日志记录器</description>
<dependencies>
<dependency>
<groupId>top.crushtj</groupId>
<groupId>com.jy</groupId>
<artifactId>xiaoyi-common</artifactId>
</dependency>
<!-- AOP 切面 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,4 +1,4 @@
package top.crushtj.framework.biz.operationlog;
package com.jy.framework.biz.operationlog;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -12,19 +12,28 @@ import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import lombok.extern.slf4j.Slf4j;
import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog;
import top.crushtj.framework.common.utils.JsonUtils;
import com.jy.framework.biz.operationlog.aspect.ApiOperationLog;
import com.jy.framework.common.utils.JsonUtils;
/**
*
* @author ayi
* @title ApiOperationLog
* @description 自定义注解用于标记需要记录操作日志的方法
* @date 2025/11/21
*/
@Slf4j
@Aspect
public class ApiOperationLogAspect {
/** 以自定义 @ApiOperationLog 注解为切点,凡是添加 @ApiOperationLog 的方法,都会执行环绕中的代码 */
@Pointcut("@annotation(top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog)")
public void apiOperationLog() {}
@Pointcut("@annotation(com.jy.framework.biz.operationlog.aspect.ApiOperationLog)")
public void apiOperationLog() {
}
/**
* 环绕
*
*
* @param joinPoint 连接点
* @return 方法执行结果
* @throws Throwable 方法执行过程中抛出的异常
@@ -65,7 +74,7 @@ public class ApiOperationLogAspect {
/**
* 获取注解的描述信息
*
*
* @param joinPoint 连接点
* @return 注解的描述信息
*/
@@ -85,7 +94,7 @@ public class ApiOperationLogAspect {
/**
* JSON 字符串
*
*
* @return 入参的 JSON 字符串
*/
private Function<Object, String> toJsonStr() {
@@ -1,4 +1,4 @@
package top.crushtj.framework.biz.operationlog.aspect;
package com.jy.framework.biz.operationlog.aspect;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
@@ -8,10 +8,10 @@ import java.lang.annotation.Target;
/**
*
* @Title: ApiOperationLog
* @Description: 自定义注解用于标记需要记录操作日志的方法
* @Author: ayi
* @Date: 2025/11/21
* @author ayi
* @title ApiOperationLog
* @description 自定义注解用于标记需要记录操作日志的方法
* @date 2025/11/21
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@@ -20,7 +20,7 @@ public @interface ApiOperationLog {
/**
* API 功能描述
*
* @return
* @return 功能描述
*/
String description() default "";
}
@@ -1,9 +1,17 @@
package top.crushtj.framework.biz.operationlog.config;
package com.jy.framework.biz.operationlog.config;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import top.crushtj.framework.biz.operationlog.ApiOperationLogAspect;
import com.jy.framework.biz.operationlog.ApiOperationLogAspect;
/**
*
* @author ayi
* @title ApiOperationLog
* @description 自定义注解用于标记需要记录操作日志的方法
* @date 2025/11/21
*/
@AutoConfiguration
public class ApiOperationLogAutoConfiguration {
@@ -1 +1 @@
top.crushtj.framework.biz.operationlog.config.ApiOperationLogAutoConfiguration
com.jy.framework.biz.operationlog.config.ApiOperationLogAutoConfiguration
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jy</groupId>
<artifactId>xiaoyi-framework</artifactId>
<version>${revision}</version>
</parent>
<packaging>jar</packaging>
<artifactId>xiaoyi-spring-boot-starter-jackson</artifactId>
<name>${project.artifactId}</name>
<description>平台基础设施层:Jackson 配置</description>
<dependencies>
<dependency>
<groupId>com.jy</groupId>
<artifactId>xiaoyi-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,74 @@
package com.jy.framework.jackson;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.YearMonthDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.YearMonthSerializer;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import com.jy.framework.common.constant.DateConstants;
import com.jy.framework.common.utils.JsonUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.TimeZone;
/**
* @author ayi
* @version V1.0
* @title JacksonConfig
* @description jackson 配置类
* @date 2026/01/06
*/
@AutoConfiguration
public class JacksonAutoConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// 忽略未知属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 设置凡是为 null 的字段,返参中均不返回,请根据项目组约定是否开启
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 设置时区
objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
// JavaTimeModule 用于指定序列化和反序列化规则
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 支持 LocalDateTime、LocalDate、LocalTime
// 支持 LocalDateTime、LocalDate、LocalTime
javaTimeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateConstants.DATE_FORMAT_Y_M_D_H_M_S));
javaTimeModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateConstants.DATE_FORMAT_Y_M_D_H_M_S));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateConstants.DATE_FORMAT_Y_M_D));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateConstants.DATE_FORMAT_Y_M_D));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateConstants.DATE_FORMAT_H_M_S));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateConstants.DATE_FORMAT_H_M_S));
// 支持 YearMonth
javaTimeModule.addSerializer(YearMonth.class, new YearMonthSerializer(DateConstants.DATE_FORMAT_Y_M));
javaTimeModule.addDeserializer(YearMonth.class, new YearMonthDeserializer(DateConstants.DATE_FORMAT_Y_M));
objectMapper.registerModule(javaTimeModule);
JsonUtils.init(objectMapper);
return objectMapper;
}
}