项目常用配置
大约 5 分钟
1. banner配置
佛祖banner
***************************************************************
* _ooOoo_ *
* o8888888o *
* 88" . "88 *
* (| ^_^ |) *
* O\ = /O *
* ____/`---'\____ *
* .' \\| |// `. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' | | *
* \ .-\__ `-` ___/-. / *
* ___`. .' /--.--\ `. . ___ *
* ."" '< `.___\_<|>_/___.' >'"". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `-. \_ __\ /__ _/ .-` / / *
* ========`-.____`-.___\_____/___.-`____.-'======== *
* `=---=' *
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *
* 佛祖保佑 永不宕机 永无BUG *
* 佛曰: *
* 写字楼里写字间,写字间里程序员; *
* 程序人员写程序,又拿程序换酒钱; *
* 酒醒只在网上坐,酒醉还来网下眠; *
* 但愿老死电脑间,不愿鞠躬老板前; *
* 奔驰宝马贵着趣,公交自行程序员; *
* 别人笑我忒疯癫,我笑自己命太贱; *
* 不见满街漂亮妹,哪个归得程序员? *
***************************************************************
* ---> Please start your performance <--- *
* ---> 请开始你的表演 <--- *
***************************************************************
读取配置文件属性
使用${}取值即可,如:获取端口号
${server.port}
2. 统一数据格式返回
代码
使用lombok和枚举类
/**
* 统一响应实体类
*
* @author zwj
* @date 2024/02/01
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
/**
* 响应码
*/
private int code;
/**
* 响应信息
*/
private String message;
/**
* 数据
*/
private T data = null;
/**
* 成功构造函数
*
* @param data 数据
*/
public Result(T data) {
this.code = ReturnCode.OPERATION_SUCCESS.getCode();
this.message = ReturnCode.OPERATION_SUCCESS.getMessage();
this.data = data;
}
/**
* 构造
*
* @param code 响应码
* @param message 消息
*/
public Result(int code, String message) {
this.code = code;
this.message = message;
}
/**
* 成功响应
*
* @param data 数据
* @return {@link Result}<{@link T}>
*/
public static <T> Result<T> success(T data) {
return new Result<>(data);
}
public static <T> Result<T> success() {
return new Result<>(null);
}
/**
* 失败响应
*
* @param message 消息
* @return {@link Result}<{@link T}>
*/
public static <T> Result<T> fail(String message) {
return new Result<>(ReturnCode.OPERATION_FAIL.getCode(), message);
}
/**
* 失败响应
*
* @param code 响应码
* @param message 消息
* @return {@link Result}<{@link T}>
*/
public static <T> Result<T> fail(int code, String message) {
return new Result<>(code, message);
}
}
响应枚举类
/**
* 响应枚举类
*
* @author zwj
* @date 2024/02/02
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum ReturnCode {
OPERATION_SUCCESS(2000, "操作成功"),
OPERATION_FAIL(5000, "操作失败"),
UNKNOWN_ERROR(5001, "服务器内部错误"),
PARAMETER_VERIFICATION_FAILED(5002, "参数校验失败"),
;
private Integer code;
private String message;
}
3. 统一异常处理
代码
全局异常
/**
* 全局异常处理程序
*
* @author zwj
* @date 2024/03/07
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 业务异常信息
*
* @param e 业务异常
* @return 异常信息
* @author zwj
* @date 17:36 2022/11/11
**/
@ResponseBody
@ExceptionHandler(value = BusinessException.class)
public Result<?> businessExceptionHandle(BusinessException e) {
log.warn("捕捉到业务类异常:", e);
return Result.fail(e.getCode(), e.getMessage());
}
/**
* 运行时异常
*
* @param e 运行时异常
* @return 异常信息
* @author zwj
* @date 17:36 2022/11/11
**/
@ResponseBody
@ExceptionHandler(value = RuntimeException.class)
public Result<?> runtimeExceptionHandle(RuntimeException e) {
log.warn("RuntimeException:", e);
return Result.fail(ReturnCode.UNKNOWN_ERROR.getCode(), e.getMessage());
}
/**
* 方法参数不可用异常
*
* @param e 方法参数异常
* @return 异常信息
* @author zwj
* @date 17:37 2022/11/11
**/
@ResponseBody
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Result<?> argumentExceptionHandle(MethodArgumentNotValidException e) {
log.warn("捕捉到运行时异常:", e);
return Result.fail(ReturnCode.PARAMETER_VERIFICATION_FAILED.getCode(),
Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
}
/**
* jsr 规范中的验证异常,嵌套检验问题
*
* @param e e
* @return {@link Result}<{@link ?}>
*/
@ResponseBody
@ExceptionHandler({ConstraintViolationException.class})
public Result<?> handleConstraintViolationException(ConstraintViolationException e) {
log.warn("ConstraintViolationException:", e);
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
String message = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
return Result.fail(ReturnCode.PARAMETER_VERIFICATION_FAILED.getCode(), message);
}
}
业务异常类
/**
* 业务异常
*
* @author zwj
* @date 2024/03/07
*/
@Getter
public class BusinessException extends RuntimeException{
private static final long serialVersionUID = 7077840387230567296L;
private final Integer code;
/**
* 根据枚举构造业务类异常
*
* @param error 异常信息
* @author zwj
* @date 17:39 2022/11/11
* @return: 业务类异常
*/
public BusinessException(ReturnCode error) {
super(error.getMessage());
this.code = error.getCode();
}
/**
* 自定义消息体构造业务类异常
*
* @param error 异常返回信息
* @param message 消息体
* @author zwj
* @date 17:39 2022/11/11
* @return: 业务异常
*/
public BusinessException(ReturnCode error, String message) {
super(message);
this.code = error.getCode();
}
/**
* 业务异常
*
* @param code 代码
* @param message 消息
*/
public BusinessException(Integer code, String message) {
super(message);
this.code =code;
}
/**
* 业务异常
*
* @param message 消息
*/
public BusinessException(String message) {
super(message);
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
}
}
4. 参数校验
了解
- Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现。hibernate validation是对这个规范的实现,并增加了校验注解如@Email、@Length等。
- Spring Validation是对hibernate validation的二次封装,用于支持spring mvc参数自动校验。
4.1 添加依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
校验使用
*. jackson常用配置
序列化和反序列化 json 的 Java 的开源框架
在spring-boot-starter-web
依赖中已经包含jackson依赖
详情
Jackson 的核心模块由三部分组成。
- jackson-core,核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
- jackson-annotations,注解包,提供标准注解功能;
- jackson-databind ,数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。
*.1 配置详情
spring:
jackson:
# 设置 java.util.Date, Calendar 序列化、反序列化的格式
date-format: yyyy-MM-dd HH:mm:ss
# 当地时区
locale: zh
# 设置全局时区
time-zone: GMT+8
# 设置对象或被@JsonInclude注解的属性的序列化方式。NON_NULL 表示不为空的属性才会序列化,具体属性可看JsonInclude.Include
# default-property-inclusion: NON_NULL
serialization:
# 禁止将 java.util.Date, Calendar 序列化为数字(时间戳)
WRITE_DATES_AS_TIMESTAMPS: false
# 序列化时,对象为 null,是否抛异常
FAIL_ON_EMPTY_BEANS: false
deserialization:
# 反序列化时,json 中包含 pojo 不存在属性时,是否抛异常
FAIL_ON_UNKNOWN_PROPERTIES: false
#一般配置ALWAYS,如配置为NON_NULL时,数据库中字段值为空时候,不返回该字段
default-property-inclusion: ALWAYS
简单的示例:
当default-property-inclusion
配置为NON_NULL时:
数据库数据:
接口返回数据:
当default-property-inclusion
配置为ALWAYS时:
接口返回数据: