《苍穹外卖》知识梳理P2
上一节中,进行了项目结构的搭建知识梳理P1
公共类说明
所有公共类都位于common模块下,由于每个包下的类很多,在此不一一列举;
1.constant包:主要存放常量类,类中只有静态常量,在需要使用时直接读取;例如其中的一个常量类:
public class MessageConstant {public static final String PASSWORD_ERROR = "密码错误";public static final String ACCOUNT_NOT_FOUND = "账号不存在";public static final String ACCOUNT_EXISTS = "账号已存在";
}
2.context包:使用 ThreadLocal 来提供线程本地变量的存储,用于在多线程环境中共享数据
public class BaseContext {//threadLocal 是一个静态的 ThreadLocal 对象,它用于存储线程本地变量public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();//setCurrentId 方法用于在当前线程中设置一个 Long 类型的标识符,将其存储在 threadLocal 中。这可以用于在当前线程的执行上下文中保留某个标识符的值。public static void setCurrentId(Long id) {threadLocal.set(id);}//getCurrentId 方法用于获取当前线程中存储的 Long 类型的标识符的值。public static Long getCurrentId() {return threadLocal.get();}//removeCurrentId 方法用于移除当前线程中存储的 Long 类型的标识符。这是为了确保在线程结束时清理 ThreadLocal 中的数据,以防止内存泄漏。public static void removeCurrentId() {threadLocal.remove();}}
3.enumeration包:主要存放枚举类,定义一系列枚举变量;
/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT}
4.exception包:主要存放自定义异常类,后边用于全局异常处理器;
/*** 业务异常,为其他所有自定义异常类的父类* 提供2个构造函数,无参构造和有参构造,有参构造可以在抛出异常时传递对应的信息;*/
public class BaseException extends RuntimeException {public BaseException() {}public BaseException(String msg) {super(msg);}}
/*** 账号被锁定异常,自定义异常,同样提供2个构造函数,并集成BaseException */
public class AccountLockedException extends BaseException {public AccountLockedException() {}public AccountLockedException(String msg) {super(msg);}}
5.json包:提供对象映射器
/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]*/
public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();//收到未知属性时不报异常this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);//反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));//注册功能模块 例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}
6.properties包:主要提供属性类,从配置文件中读取相应的属性,并注册成为Bean,可以被注入到其他类比如拦截器,配置类等中;
@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;}
7.Result包:统一返回数据结果,将所有Controller返回的结果都处理成code,msg,data的格式;
/*** 后端统一返回结果* @param <T>*/
@Data
public class Result<T> implements Serializable {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据public static <T> Result<T> success() {Result<T> result = new Result<T>();result.code = 1;return result;}public static <T> Result<T> success(T object) {Result<T> result = new Result<T>();result.data = object;result.code = 1;return result;}public static <T> Result<T> error(String msg) {Result result = new Result();result.msg = msg;result.code = 0;return result;}}
/*** 封装分页查询结果*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {private long total; //总记录数private List records; //当前页数据集合}
8.uitls包:主要提供一些工具类,工具类的所有方法都设置为静态,可以被直接调用;
public class JwtUtil {/*** 生成jwt* 使用Hs256算法, 私匙使用固定秘钥** @param secretKey jwt秘钥* @param ttlMillis jwt过期时间(毫秒)* @param claims 设置的信息* @return*/public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {// 指定签名的时候使用的签名算法,也就是header那部分SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成JWT的时间long expMillis = System.currentTimeMillis() + ttlMillis;Date exp = new Date(expMillis);// 设置jwt的bodyJwtBuilder builder = Jwts.builder()// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setClaims(claims)// 设置签名使用的签名算法和签名使用的秘钥.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))// 设置过期时间.setExpiration(exp);return builder.compact();}/*** Token解密** @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个* @param token 加密后的token* @return*/public static Claims parseJWT(String secretKey, String token) {// 得到DefaultJwtParserClaims claims = Jwts.parser()// 设置签名的秘钥.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))// 设置需要解析的jwt.parseClaimsJws(token).getBody();return claims;}
}