zhouyu 9 months ago
parent b0b6fbdcaf
commit ac724ead75

@ -14,26 +14,14 @@ import javax.annotation.PostConstruct;
* @CONTACT 317758022@qq.com
* @DESC redisredishash
*/
// 使用Spring框架的@Component注解将该类标记为一个组件意味着Spring会对这个类进行管理使其能够参与到依赖注入等Spring容器的相关功能中方便在其他需要使用该类实例的地方通过自动注入等方式获取实例从而实现不同组件之间的协作。
@Component
// 使用lombok的@Slf4j注解用于自动生成日志相关的代码方便在类中记录各种操作相关的日志信息便于后续查看操作情况以及进行问题排查例如在初始化Jedis连接池时出现成功或失败的情况都可以通过日志清晰地记录下来方便了解系统状态以及定位问题。
@Slf4j
public class JedisPoolWrapper {
// 通过Spring的依赖注入机制使用@Autowired注解自动注入Parameters类型的实例Parameters类应该是用于存储系统相关配置参数的类在这里主要是期望从中获取与Redis连接池配置相关的参数例如最大连接数、最大空闲连接数等信息。
@Autowired
private Parameters parameters;
// 定义一个私有成员变量jedisPool用于存储Jedis连接池对象初始化为null后续会在初始化方法中根据配置参数来创建实际的Jedis连接池实例。
private JedisPool jedisPool = null;
/**
* 使Spring@PostConstruct
*
* JedisPoolConfigJedisPoolConfigJedis
* ParametersRedisJedisPoolConfigparameters.getRedisMaxTotal()config.setMaxTotalJedisPoolConfig
* 使JedisPoolConfigParametersRedisparameters.getRedisHost()parameters.getRedisPort()2000"xxx"JedisPooljedisPoolJedis
* log.errorredis便log.inforedis
*/
@PostConstruct
public void init(){
try {
@ -48,12 +36,7 @@ public class JedisPoolWrapper {
}
}
/**
* JedisPool
* JedisPoolJedisRedis
* initJedisPoolinitJedisPooljedisPoolnullnullnull
*/
public JedisPool getJedisPool() {
return jedisPool;
}
}
}

@ -10,36 +10,24 @@ import org.springframework.stereotype.Component;
* @CONTACT 317758022@qq.com
* @DESC
*/
// 使用Spring框架的@Component注解将这个类标记为一个组件意味着该类会被Spring容器进行管理能够参与到依赖注入等Spring相关的功能中方便在其他需要使用此类实例的地方通过自动注入等方式获取实例实现不同组件之间的协作。
@Component
// 使用lombok的@Data注解该注解会自动为类生成一系列常用方法比如针对类中所有非静态成员变量这里包含了redis相关配置属性以及zk相关配置属性等的Getter和Setter方法方便在其他地方获取和设置这些变量的值同时还会生成equals、hashCode、toString方法等减少了手动编写这些重复代码的工作量让代码更加简洁高效。
@Data
public class Parameters {
// 以下是Redis相关配置参数的定义部分通过Spring的@Value注解结合配置文件中的属性占位符例如${redis.host}来从配置文件通常是application.properties或application.yml等中读取对应的配置值并注入到对应的成员变量中。
/*****redis config start*******/
// 使用@Value("${redis.host}")注解,从配置文件中读取名为"redis.host"的配置属性值并将其注入到这个私有成员变量redisHost中该变量用于存储Redis服务器的主机地址以便后续在初始化Jedis连接池等操作中使用该地址来连接Redis服务器。
@Value("${redis.host}")
private String redisHost;
// 使用@Value("${redis.port}")注解,从配置文件中读取名为"redis.port"的配置属性值并将其注入到这个私有成员变量redisPort中该变量用于存储Redis服务器的端口号用于明确连接Redis服务器时的端口信息确保能够正确地建立连接。
@Value("${redis.port}")
private int redisPort;
// 此处注解可能存在配置属性名与变量含义不匹配的情况(实际按名称看应该是获取"redis.max-total",但变量名含义是最大空闲连接数),按正确逻辑理解,应该是从配置文件中读取名为"redis.max-total"的配置属性值注入到这个私有成员变量redisMaxTotal中该变量用于存储Jedis连接池中允许的最大连接数量控制连接池的整体规模避免过多连接造成资源浪费或性能问题。
@Value("${redis.max-idle}")
private int redisMaxTotal;
// 同样此处注解可能存在配置属性名与变量含义不匹配的情况(实际按名称看应该是获取"redis.max-idle",但变量名含义是最大活跃连接数),按正确逻辑理解,应该是从配置文件中读取名为"redis.max-idle"的配置属性值注入到这个私有成员变量redisMaxIdle中该变量用于存储Jedis连接池中允许的最大空闲连接数量合理控制空闲连接资源提高连接池的利用效率。
@Value("${redis.max-total}")
private int redisMaxIdle;
// 使用@Value("${redis.max-wait-millis}")注解,从配置文件中读取名为"redis.max-wait-millis"的配置属性值并将其注入到这个私有成员变量redisMaxWaitMillis中该变量用于存储获取Jedis连接时的最大等待时间单位是毫秒如果在规定时间内无法获取到连接可能会抛出相应的异常以此来控制获取连接的超时情况避免长时间等待造成系统阻塞等问题。
@Value("${redis.max-wait-millis}")
private int redisMaxWaitMillis;
/*****redis config end*******/
// 以下是Zookeepercurator是Zookeeper的客户端框架相关配置参数的定义部分同样通过@Value注解结合配置文件中的属性占位符来读取配置值并注入到对应的成员变量中。
/*****curator config start*******/
// 使用@Value("${zk.host}")注解,从配置文件中读取名为"zk.host"的配置属性值并将其注入到这个私有成员变量zkHost中该变量用于存储Zookeeper服务器的主机地址后续在使用curator客户端连接Zookeeper服务器时会用到这个地址信息用于构建正确的连接路径等操作。
@Value("${zk.host}")
private String zkHost;
/*****curator config end*******/
}
}

@ -7,59 +7,40 @@ package com.njupt.swg.common.constants;
* @DESC
*/
public class Constants {
// 此部分定义了一系列自定义的状态码常量,用于在整个应用中统一标识不同的响应状态,方便在不同的业务逻辑处理中进行状态判断与相应的操作。
/**自定义状态码 start**/
// 定义一个整型常量RESP_STATUS_OK值为200通常用于表示请求处理成功的状态。在接口返回响应给客户端时如果业务操作顺利完成就可以使用这个状态码来告知客户端请求已成功处理后续客户端可根据此状态码进行相应的后续操作比如正常展示返回的数据等。
public static final int RESP_STATUS_OK = 200;
// 定义整型常量RESP_STATUS_NOAUTH值为401该常量代表未授权的状态。当用户尝试访问某个受保护的资源或接口但没有提供有效的认证信息或者权限不足时服务器会返回这个状态码给客户端提示客户端需要进行身份认证或者获取相应权限后才能再次发起访问请求。
public static final int RESP_STATUS_NOAUTH = 401;
// 定义整型常量RESP_STATUS_INTERNAL_ERROR值为500用于表示服务器内部出现错误的情况。例如在服务器端代码执行过程中发生了未预期的异常导致无法正常完成请求处理时就会返回这个状态码给客户端告知客户端请求处理失败是由于服务器内部问题客户端可以根据此情况提示用户联系系统管理员等进一步排查问题。
public static final int RESP_STATUS_INTERNAL_ERROR = 500;
// 定义整型常量RESP_STATUS_BADREQUEST值为400此常量表示请求的参数存在问题比如请求参数格式不符合接口要求、缺少必要的参数等情况。当服务器接收到这样的请求时会返回这个状态码给客户端让客户端知晓需要修正请求参数后重新发起请求以保证请求能够被正确处理。
public static final int RESP_STATUS_BADREQUEST = 400;
/**自定义状态码 end**/
// 以下是关于Redis中存储用户相关数据时使用的键key前缀的常量定义通过统一使用这个前缀能方便地在Redis中对用户相关的缓存数据进行分类管理和查找等操作。
/***redis user相关的key以这个打头**/
public static final String TOKEN_PREFIX = "user_";
// 这里定义了一个内部接口RedisCacheExtime用于集中管理用户登录信息在Redis中的过期时间相关常量这样做可以使代码中涉及到该过期时间的地方保持一致性并且通过接口的形式将相关逻辑进行了封装和分组方便后续维护与修改。
/**
* redis
*/
public interface RedisCacheExtime{
// 定义一个整型常量REDIS_SESSION_EXTIME用于表示用户登录在Redis中的缓存过期时间其值计算为60 * 60 * 10也就是30分钟按照每秒为单位换算。意味着在用户登录后相关的登录状态等信息在Redis缓存中会保存30分钟一旦超过这个时间缓存数据将会自动过期后续如果需要调整用户登录缓存的过期时长只需在这个接口内修改该常量的值即可统一生效。
int REDIS_SESSION_EXTIME = 60 * 60 * 10;//30分钟
}
// 以下是针对用户注册时判断重复的参数类型所定义的常量,用于明确在注册流程中需要检查哪些具体参数是否已被其他用户使用,从而保证注册信息的唯一性。
/** 用户注册判断重复的参数类型 start **/
// 定义一个字符串常量EMAIL值为"email",在用户注册的逻辑中,使用这个常量来标识需要检查用户输入的邮箱地址是否已经被其他用户注册过,比如在数据库查询验证环节,通过这个常量来指定要比对的字段为邮箱字段,以防止重复注册相同邮箱的情况出现。
public static final String EMAIL = "email";
// 定义字符串常量USERNAME值为"username",同样在用户注册过程中,该常量用于表明要检查用户名是否重复,在进行数据库查询或者其他验证操作时,依据这个常量来确定是针对用户名这个字段进行重复性的判断,确保每个用户名在系统中具有唯一性。
public static final String USERNAME = "username";
/** 用户注册判断重复的参数类型 end **/
// 定义了一个内部接口Role用于对用户在系统中不同角色的相关常量进行统一管理这样在涉及用户角色判断、权限分配以及业务逻辑根据角色进行不同处理等场景时可以清晰地通过这些常量来区分不同的用户角色提高代码的可读性和可维护性。
/** 用户角色 **/
public interface Role{
// 定义整型常量ROLE_CUSTOME值为0用于表示普通用户这一角色。在系统的权限控制体系中普通用户通常具有相对受限的操作权限只能进行一些常规的业务操作通过这个常量可以方便地在代码中对普通用户相关的权限判断、业务逻辑处理等进行标识和区分。
int ROLE_CUSTOME = 0;//普通用户
// 定义整型常量ROLE_ADMIN值为1用来代表管理员用户角色。管理员用户在系统中往往拥有更高的权限能够执行诸如系统配置、数据管理等更多的关键操作借助这个常量可以在代码里清晰地识别出管理员角色并进行相应的权限相关处理。
int ROLE_ADMIN = 1;//管理员用户
}
// 定义一个字符串常量USER_REGISTER_DISTRIBUTE_LOCK_PATH值为"/user_reg"该常量用于指定在分布式环境下用户注册操作时所使用的分布式锁的路径信息。在分布式系统中为了保证用户注册操作的原子性和一致性比如避免多个并发的注册请求同时对用户名、邮箱等唯一性验证和写入数据库等关键操作产生冲突会使用分布式锁进行控制而这个常量就是定义了该分布式锁在相应的分布式锁管理组件如基于Zookeeper等实现的分布式锁中的具体路径。
/**用户注册分布式锁路径***/
public static final String USER_REGISTER_DISTRIBUTE_LOCK_PATH = "/user_reg";
}
}

@ -14,29 +14,20 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @CONTACT 317758022@qq.com
* @DESC
*/
// 使用Spring框架的@ControllerAdvice注解表明这个类是一个全局的异常处理类它可以拦截并处理在整个应用中由Spring管理的控制器Controller抛出的异常能够统一对异常情况进行处理避免在每个控制器方法中都单独编写异常处理逻辑使代码更加简洁和易于维护。
@ControllerAdvice
// 使用@ResponseBody注解结合@ControllerAdvice注解意味着这个类中处理异常的方法返回的结果会直接作为响应体ResponseBody返回给客户端通常是以JSON等格式的数据进行响应方便客户端获取异常相关的信息并进行相应展示或处理。
@ResponseBody
// 使用lombok的@Slf4j注解用于自动生成日志相关的代码方便在类中记录各种异常相关的日志信息便于后续查看异常情况以及进行问题排查比如记录异常的详细信息、错误消息等有助于定位和解决出现的问题。
@Slf4j
public class ExceptionHandlerAdvice {
// 使用Spring的@ExceptionHandler注解指定这个方法用于处理Exception类型的异常也就是可以捕获所有未被更具体的异常处理器处理的异常情况它是一种兜底的异常处理方式确保任何未被处理的异常都能在这里被统一处理避免程序因异常而崩溃。
@ExceptionHandler(Exception.class)
public ServerResponse handleException(Exception e){
// 使用日志记录异常的详细信息通过log.error方法记录异常的消息内容e.getMessage()以及完整的异常堆栈信息e方便后续查看具体的异常原因和出现异常的位置等情况有助于进行问题排查和定位。
log.error(e.getMessage(),e);
// 创建并返回一个ServerResponse类型的响应对象调用ServerResponse的静态方法createByErrorCodeMessage传入自定义的系统内部错误状态码Constants.RESP_STATUS_INTERNAL_ERROR通常表示服务器内部出现了问题以及提示客户端的消息"系统异常,请稍后再试"),告知客户端请求处理出现了系统级别的异常,让客户端可以根据这个提示信息进行相应的操作,比如提示用户稍后重新发起请求等。
return ServerResponse.createByErrorCodeMessage(Constants.RESP_STATUS_INTERNAL_ERROR,"系统异常,请稍后再试");
}
// 使用@ExceptionHandler注解指定这个方法用于处理SnailmallException类型的异常这是一个自定义的异常类型意味着当应用中抛出了这个特定类型的异常时会由这个方法来进行专门的处理相较于处理通用Exception类型的异常这里可以根据自定义异常的特点进行更针对性的响应处理。
@ExceptionHandler(SnailmallException.class)
public ServerResponse handleException(SnailmallException e){
// 同样记录异常的详细信息到日志中,方便后续排查问题,记录异常的消息内容以及完整的异常堆栈信息。
log.error(e.getMessage(),e);
// 创建并返回一个ServerResponse类型的响应对象调用ServerResponse的静态方法createByErrorCodeMessage传入自定义异常中携带的状态码e.getExceptionStatus()通常自定义异常会根据不同的业务场景设置不同的状态码来表示具体的错误情况以及异常的消息内容e.getMessage()),这样可以将更具体的错误信息和对应的状态码返回给客户端,让客户端能够准确知晓出现的具体问题并进行相应处理。
return ServerResponse.createByErrorCodeMessage(e.getExceptionStatus(),e.getMessage());
}
}
}

@ -9,19 +9,14 @@ import lombok.Getter;
* @CONTACT 317758022@qq.com
* @DESC
*/
// 使用lombok的@Getter注解该注解会自动为类中的私有成员变量这里是exceptionStatus生成对应的Getter方法方便在其他地方获取这个变量的值避免手动编写Getter方法的重复代码使代码更加简洁。
@Getter
// 定义了一个名为SnailmallException的类它继承自Java内置的RuntimeException类意味着这是一个运行时异常不需要在方法声明中显式地抛出与受检异常不同在程序运行过程中如果出现符合其定义的异常情况时可以直接抛出由合适的异常处理器来捕获处理。
public class SnailmallException extends RuntimeException{
// 定义一个私有整型成员变量exceptionStatus用于存储异常对应的状态码初始值设置为ResponseEnum.ERROR.getCode()这里推测ResponseEnum是一个枚举类型用于统一管理各种响应状态码相关的信息通过调用其ERROR对应的getCode()方法获取默认的错误状态码作为初始值,后续可以根据具体的异常情况进行修改。
private int exceptionStatus = ResponseEnum.ERROR.getCode();
// 定义了一个构造函数接收一个字符串类型的参数msg用于创建一个SnailmallException实例。在构造函数内部通过调用父类RuntimeException的构造函数并传入msg参数将异常消息传递给父类这样在抛出该异常时就能携带这个自定义的消息信息方便在异常处理等地方获取并展示具体的异常原因给用户或进行日志记录等操作。
public SnailmallException(String msg){
super(msg);
}
// 定义了另一个构造函数接收一个整型参数code和一个字符串参数msg用于创建一个更具定制化的SnailmallException实例。在这个构造函数中首先同样调用父类的构造函数将msg参数传递给父类以设置异常消息然后将传入的code参数赋值给exceptionStatus变量用于覆盖默认的异常状态码使得可以根据不同的业务场景设置不同的状态码来准确表示具体的异常情况方便在异常处理逻辑中根据状态码进行不同的处理操作。
public SnailmallException(int code,String msg){
super(msg);
exceptionStatus = code;

@ -14,93 +14,66 @@ import java.io.Serializable;
* @CONTACT 317758022@qq.com
* @DESC
*/
// 使用lombok的@Getter注解该注解会自动为类中的私有成员变量这里的status、msg和data生成对应的Getter方法方便在其他地方获取这些变量的值避免手动编写Getter方法的重复代码使得代码更加简洁在使用ServerResponse对象时能够轻松获取其包含的状态码、消息以及业务数据等信息。
@Getter
// 使用Jackson的@JsonSerialize注解来配置该类在序列化例如转换为JSON格式以便在网络传输或者存储时使用时的行为这里设置include属性为JsonSerialize.Inclusion.NON_NULL表示在序列化过程中只包含非空的属性值也就是如果某个属性如msg或者data的值为null那么在最终序列化生成的JSON数据中就不会包含对应的字段这样可以减少传输的数据量并且使序列化后的结果更加符合实际需求避免传递不必要的空值信息。
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
// 让这个类实现Serializable接口表示该类的对象可以被序列化和反序列化这在很多场景下非常有用比如将服务器响应对象存储到文件中、在网络中传输响应对象等情况时通过序列化将对象转换为字节流进行存储或传输然后再通过反序列化将字节流还原为对象实现数据的持久化和跨网络的交互等功能。
public class ServerResponse<T> implements Serializable {
// 定义一个私有整型成员变量status用于存储响应的状态码通过不同的状态码来表示响应的不同情况例如成功、失败、需要登录等在业务逻辑中可以根据这个状态码来判断请求处理的结果状态进而进行相应的后续操作。
private int status;
// 定义一个私有字符串成员变量msg用于存储响应的提示消息这个消息可以是对响应状态的具体描述比如在成功时可以是“操作成功”在失败时可以是具体的错误原因等方便客户端如前端应用获取并展示给用户让用户了解操作的结果情况。
private String msg;
// 定义一个泛型类型的私有成员变量data用于存储具体的业务数据这里使用泛型使得这个响应类可以适用于不同类型的业务数据返回情况例如可以返回用户信息、商品列表等各种类型的数据增加了类的通用性和灵活性。
private T data;
// 定义一个默认的无参构造函数主要用于在一些情况下比如反序列化时创建一个空的ServerResponse对象后续可以再通过Setter方法虽然这里没有显式定义但可以通过lombok的@Setter注解自动生成或者手动编写或者其他方式来设置对象的各个属性值。
public ServerResponse(){}
// 定义一个私有构造函数接收一个整型参数status用于创建一个只设置了状态码的ServerResponse对象通常在一些内部逻辑中已知具体的状态码但暂时不需要设置消息和业务数据时可以使用这个构造函数来创建对象后续再根据具体情况补充其他属性值。
private ServerResponse(int status){
this.status = status;
}
// 定义一个私有构造函数接收一个整型参数status和一个字符串参数msg用于创建一个设置了状态码和提示消息的ServerResponse对象在已知响应状态码以及对应的描述消息时可以通过这个构造函数来初始化对象方便在业务逻辑中根据具体情况返回相应的响应对象告知客户端操作的结果情况。
private ServerResponse(int status,String msg){
this.status = status;
this.msg = msg;
}
// 定义一个私有构造函数接收一个整型参数status和一个泛型参数data用于创建一个设置了状态码和业务数据的ServerResponse对象在请求处理成功且有具体业务数据需要返回给客户端时可以使用这个构造函数来构建包含相应数据的响应对象让客户端能够获取到操作结果以及所需的数据信息。
private ServerResponse(int status,T data){
this.status = status;
this.data = data;
}
// 定义一个私有构造函数接收一个整型参数status、一个字符串参数msg和一个泛型参数data用于创建一个完整设置了状态码、提示消息以及业务数据的ServerResponse对象这是最全面的构造方式在各种不同的业务场景下根据实际的响应情况包含状态、具体描述以及要返回的数据都可以通过这个构造函数来创建合适的响应对象返回给客户端。
private ServerResponse(int status,String msg,T data){
this.status = status;
this.msg = msg;
this.data = data;
}
// 使用Jackson的@JsonIgnore注解标记这个方法该注解表示在序列化对象时忽略这个方法也就是不会将这个方法的返回值作为字段包含在序列化后的结果中例如JSON数据中不会出现这个方法对应的字段。这个方法用于判断响应是否成功通过比较当前对象的状态码与ResponseEnum.SUCCESS通常是一个枚举类型用于统一管理响应相关的状态码等信息中定义的成功状态码是否相等来返回一个布尔值如果相等则表示响应成功否则表示响应失败方便在业务逻辑中快速判断响应的结果状态。
@JsonIgnore
public boolean isSuccess(){
return this.status == ResponseEnum.SUCCESS.getCode();
}
/**
* 便ServerResponse便
*/
/**
*
*/
// 这个静态方法用于创建一个表示成功的ServerResponse对象使用ResponseEnum.SUCCESS中定义的状态码和描述信息来初始化对象通常在业务操作顺利完成且没有额外需要返回的具体业务数据以及自定义消息时可以调用这个方法返回一个简单表示成功的响应对象给客户端告知客户端请求处理成功。
public static <T>ServerResponse<T> createBySuccess(){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),ResponseEnum.SUCCESS.getDesc());
}
// 这个静态方法用于创建一个带有自定义提示消息的成功响应对象接收一个字符串参数message使用ResponseEnum.SUCCESS中定义的状态码以及传入的自定义消息来初始化对象在业务操作成功且希望返回一个特定的提示消息给客户端比如“新增用户成功”等可以调用这个方法让客户端展示这个自定义的消息给用户告知具体的成功情况。
public static <T>ServerResponse<T> createBySuccessMessage(String message){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),message);
}
// 这个静态方法用于创建一个包含业务数据的成功响应对象接收一个泛型参数data使用ResponseEnum.SUCCESS中定义的状态码以及传入的业务数据来初始化对象在业务操作成功且有具体的数据需要返回给客户端比如查询用户列表成功后返回用户列表数据等调用这个方法来构建包含相应数据的响应对象方便客户端获取并使用这些数据进行后续操作如展示数据等。
public static <T>ServerResponse<T> createBySuccess(T data){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),data);
}
// 这个静态方法是创建成功响应对象最全面的方式接收一个字符串参数message和一个泛型参数data使用ResponseEnum.SUCCESS中定义的状态码、传入的自定义消息以及业务数据来初始化对象在业务操作成功且既有自定义的提示消息又有具体业务数据需要返回给客户端时调用这个方法可以创建一个完整的包含状态、消息和数据的响应对象返回给客户端满足各种复杂的成功响应场景需求。
public static <T>ServerResponse<T> createBySuccess(String message,T data){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),message,data);
}
/**
* 便ServerResponse便
*/
/**
*
*/
// 这个静态方法用于创建一个表示一般性失败的ServerResponse对象使用ResponseEnum.ERROR中定义的状态码和描述信息来初始化对象通常在业务操作出现未明确的错误情况且没有更具体的错误消息需要返回时可以调用这个方法返回一个简单表示失败的响应对象给客户端告知客户端请求处理出现错误。
public static <T>ServerResponse<T> createByError(){
return new ServerResponse<>(ResponseEnum.ERROR.getCode(),ResponseEnum.ERROR.getDesc());
}
// 这个静态方法用于创建一个带有自定义错误提示消息的失败响应对象接收一个字符串参数msg使用ResponseEnum.ERROR中定义的状态码以及传入的自定义消息来初始化对象在业务操作失败且希望返回一个具体的错误原因给客户端比如“用户名已存在”等可以调用这个方法让客户端展示这个自定义的错误消息给用户告知具体的失败情况。
public static <T>ServerResponse<T> createByErrorMessage(String msg){
return new ServerResponse<>(ResponseEnum.ERROR.getCode(),msg);
}
// 这个静态方法用于创建一个带有自定义状态码和错误提示消息的失败响应对象接收一个整型参数code和一个字符串参数msg使用传入的状态码和消息来初始化对象在业务操作失败且需要根据具体的业务场景返回特定的状态码以及对应的错误消息时比如不同的业务模块有不同的错误状态码定义等情况调用这个方法可以构建相应的符合要求的失败响应对象返回给客户端方便客户端根据状态码和消息进行相应的处理如提示用户、进行不同的错误提示展示等。
public static <T>ServerResponse<T> createByErrorCodeMessage(int code,String msg){
return new ServerResponse<>(code,msg);
}
}
}

@ -10,55 +10,39 @@ import javax.servlet.http.HttpServletResponse;
/**
* cookie
*/
// 使用lombok的@Slf4j注解用于自动生成日志相关的代码方便在类中记录各种操作相关的日志信息便于后续查看操作情况以及进行问题排查例如在对Cookie进行写入、读取、删除等操作时通过日志记录关键信息有助于了解Cookie操作的执行情况以及可能出现的问题。
@Slf4j
public class CookieUtil {
// 定义一个私有静态常量字符串COOKIE_DOMAIN用于指定Cookie的作用域域名这里设置为"oursnail.cn"意味着该Cookie在这个域名及其子域名下有效在设置和操作Cookie时会用到这个域名信息来确定其作用范围。
private final static String COOKIE_DOMAIN = "oursnail.cn";
// 定义一个私有静态常量字符串COOKIE_NAME用于指定Cookie的名称这里设置为"snailmall_login_token"通过这个固定的名称来标识特定用途如用户登录相关的Cookie方便在后续的读取、操作等过程中进行识别和区分。
private final static String COOKIE_NAME = "snailmall_login_token";
/**
* CookieCookieHttpServletResponse便Cookie
*
* @param response HttpServletResponseCookie使
* @param token Cookietoken"snailmall_login_token"Cookie
* cookie
* @param response
* @param token
*/
public static void writeLoginToken(HttpServletResponse response, String token) {
// 创建一个名为"snailmall_login_token"的Cookie对象将传入的token作为其值后续会对这个Cookie对象进行一系列属性设置使其符合业务需求。
Cookie ck = new Cookie(COOKIE_NAME, token);
// 设置Cookie的作用域域名使用之前定义好的COOKIE_DOMAIN常量确保该Cookie在指定的域名"oursnail.cn"及其子域名下有效这样在该域名相关的页面访问时浏览器会带上这个Cookie信息。
public static void writeLoginToken(HttpServletResponse response,String token){
Cookie ck = new Cookie(COOKIE_NAME,token);
ck.setDomain(COOKIE_DOMAIN);
// 设置Cookie的路径为根目录"/"表示该Cookie在整个网站的所有页面路径下都有效无论访问哪个页面浏览器都会将这个Cookie发送给服务器方便在不同页面间共享该Cookie所携带的信息比如登录状态等
ck.setPath("/");//设值在根目录
// 设置HttpOnly属性为true这意味着该Cookie不能通过客户端脚本如JavaScript访问主要是为了增强安全性避免恶意脚本通过获取Cookie信息来进行攻击例如防止跨站脚本攻击XSS获取用户登录相关的敏感信息。
ck.setHttpOnly(true);//不允许通过脚本访问cookie,避免脚本攻击
// 设置Cookie的最大存活时间这里设置为一年60 * 60 * 24 * 365秒表示该Cookie在客户端保存一年后才会过期失效如果设置为 -1则表示永久有效若不设置这个属性即maxage不设置Cookie就不会写入硬盘只会临时保存在内存中且只在当前页面有效下次访问其他页面时该Cookie就不存在了。
ck.setMaxAge(60 * 60 * 24 * 365);//一年,-1表示永久,单位是秒maxage不设置的话cookie就不会写入硬盘只会写在内存只在当前页面有效
// 使用日志记录即将写入的Cookie的名称和值信息方便后续查看Cookie的写入情况例如在排查是否正确写入了期望的Cookie等问题时可以通过日志进行确认。
log.info("write cookieName:{},cookieValue:{}", ck.getName(), ck.getValue());
// 将设置好的Cookie添加到HttpServletResponse对象中这样在响应发送给客户端时客户端浏览器就会接收到并保存这个Cookie从而实现登录相关信息通过token体现在客户端的存储。
ck.setMaxAge(60*60*24*365);//一年,-1表示永久,单位是秒maxage不设置的话cookie就不会写入硬盘只会写在内存只在当前页面有效
log.info("write cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
response.addCookie(ck);
}
/**
* HttpServletRequest"snailmall_login_token"CookieCookieCookienull
*
* @param request HttpServletRequestCookie便Cookie
* @return "snailmall_login_token"CookienullCookie访
* cookie
* @param request
* @return
*/
public static String readLoginToken(HttpServletRequest request) {
// 从HttpServletRequest对象中获取客户端发送过来的所有Cookie数组如果没有Cookie则返回null。
public static String readLoginToken(HttpServletRequest request){
Cookie[] cks = request.getCookies();
if (cks!= null) {
// 遍历获取到的Cookie数组逐个检查每个Cookie的名称是否与期望的"snailmall_login_token"一致。
for (Cookie ck : cks) {
// 使用日志记录当前遍历到的Cookie的名称和值信息方便后续查看Cookie的读取情况例如排查是否正确遍历到了所有Cookie以及是否有符合要求的Cookie等问题时可以通过日志进行分析。
log.info("cookieName:{},cookieBValue:{}", ck.getName(), ck.getValue());
if (StringUtils.equals(ck.getName(), COOKIE_NAME)) {
// 如果找到名称匹配的Cookie再次使用日志记录这个匹配的Cookie的名称和值信息然后返回其值以便调用者获取到登录相关的Cookie中存储的信息如登录令牌等进行后续操作。
log.info("return cookieName:{},cookieBValue:{}", ck.getName(), ck.getValue());
if(cks != null){
for(Cookie ck:cks){
log.info("cookieName:{},cookieBValue:{}",ck.getName(),ck.getValue());
if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
log.info("return cookieName:{},cookieBValue:{}",ck.getName(),ck.getValue());
return ck.getValue();
}
}
@ -67,31 +51,24 @@ public class CookieUtil {
}
/**
* "snailmall_login_token"CookieCookieCookie使0Cookie
*
* @param request HttpServletRequestCookie便Cookie
* @param response HttpServletResponseCookie
*
* @param request
* @param response
*/
public static void delLoginToken(HttpServletRequest request, HttpServletResponse response) {
// 从HttpServletRequest对象中获取客户端发送过来的所有Cookie数组如果没有Cookie则无需进行后续删除操作。
public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){
Cookie[] cks = request.getCookies();
if (cks!= null) {
// 遍历获取到的Cookie数组逐个检查每个Cookie的名称是否与期望的"snailmall_login_token"一致。
for (Cookie ck : cks) {
if (StringUtils.equals(ck.getName(), COOKIE_NAME)) {
// 如果找到名称匹配的Cookie先设置其作用域域名使用之前定义好的COOKIE_DOMAIN常量确保修改的是正确域名下的该Cookie。
if(cks != null){
for(Cookie ck:cks) {
if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
ck.setDomain(COOKIE_DOMAIN);
// 设置Cookie的路径为根目录"/"),保持与之前设置一致,使其在整个网站的所有页面路径下都能正确执行删除操作。
ck.setPath("/");
// 设置Cookie的最大存活时间为0表示让客户端立即删除这个Cookie使其失效不再在后续的请求中携带该Cookie信息。
ck.setMaxAge(0);//0表示消除此cookie
// 使用日志记录即将删除的Cookie的名称和值信息方便后续查看Cookie的删除情况例如在排查是否正确删除了期望的Cookie等问题时可以通过日志进行确认。
log.info("del cookieName:{},cookieBValue:{}", ck.getName(), ck.getValue());
// 将设置为失效状态的Cookie添加到HttpServletResponse对象中发送给客户端客户端浏览器接收到这个响应后会根据设置删除对应的Cookie从而实现注销时删除登录相关Cookie的功能。
log.info("del cookieName:{},cookieBValue:{}",ck.getName(),ck.getValue());
response.addCookie(ck);
return;
}
}
}
}
}
}

@ -13,45 +13,21 @@ import java.util.Date;
* @DESC
*/
public class DateTimeUtil {
// 这里的注释表明该工具类可能使用了joda-time库来进行日期时间相关的操作joda-time是一个功能强大的处理日期、时间的第三方库相比于Java原生的日期时间API它提供了更方便、易用且功能丰富的方法来操作日期时间数据。
//joda-time
// 以下注释说明了这个工具类主要实现的两个功能方向即把字符串类型的日期时间表示转换为Date类型str->Date以及把Date类型的日期时间转换为字符串类型Date->str方便在不同的业务场景中对日期时间数据进行格式转换以满足存储、展示等各种需求。
//str->Date
//Date->str
// 定义一个公共静态常量字符串STANDARD_FORMAT用于指定一种标准的日期时间格式这里设置为"yyyy-MM-dd HH:mm:ss",也就是年-月-日 时:分:秒的格式,在一些方法中如果没有指定具体的日期时间格式参数时,会默认使用这个标准格式来进行日期时间和字符串之间的转换操作。
public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* dateTimeStrformatStrJavaDate
* joda-timeDateTimeFormatterDateTime
* formatStrDateTimeFormatter
* 使DateTimeFormatterdateTimeStrDateTimeDateTimejoda-time便
* DateTimeJavaDateDate便使Date使
*
* @param dateTimeStr formatStr
* @param formatStr "yyyy-MM-dd HH:mm:ss"
* @return Java Datejoda-time
*/
public static Date strToDate(String dateTimeStr, String formatStr){
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(formatStr);
DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
return dateTime.toDate();
}
/**
* Java Date
* DatenullStringUtils.EMPTY
* DatenullDatejoda-timeDateTimeDateTime便
* 使DateTimetoStringformatStr便Date使
*
* @param date Java Datenull
* @param formatStr "yyyy-MM-dd HH:mm:ss"Date
* @return Datenull
*/
public static String dateToStr(Date date, String formatStr){
public static String dateToStr(Date date,String formatStr){
if(date == null){
return StringUtils.EMPTY;
}
@ -59,13 +35,6 @@ public class DateTimeUtil {
return dateTime.toString(formatStr);
}
/**
* dateTimeStrSTANDARD_FORMAT"yyyy-MM-dd HH:mm:ss"JavaDate
* strToDate(String dateTimeStr, String formatStr)使DateTimeFormatter便
*
* @param dateTimeStr "yyyy-MM-dd HH:mm:ss"
* @return Java Datejoda-time
*/
//固定好格式
public static Date strToDate(String dateTimeStr){
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(STANDARD_FORMAT);
@ -73,13 +42,6 @@ public class DateTimeUtil {
return dateTime.toDate();
}
/**
* Java DateSTANDARD_FORMAT"yyyy-MM-dd HH:mm:ss"
* dateToStr(Date date, String formatStr)DatenullnullDateDateTime便Date
*
* @param date Java Datenull
* @return "yyyy-MM-dd HH:mm:ss"Datenull
*/
public static String dateToStr(Date date){
if(date == null){
return StringUtils.EMPTY;
@ -88,15 +50,6 @@ public class DateTimeUtil {
return dateTime.toString(STANDARD_FORMAT);
}
/**
* Java Date19701100:00:00 UTC
* Datenullnull
* nullDateSimpleDateFormat"yyyy-MM-dd HH:mm:ss"DateSimpleDateFormatparseDateDateDategetTime19701100:00:00 UTC便使使
*
* @param date Java Datenullnull
* @return Datenullnull
* @throws ParseException 使SimpleDateFormatparse
*/
//Date -> 时间戳
public static Long dateToChuo(Date date) throws ParseException {
if(date == null){
@ -106,18 +59,10 @@ public class DateTimeUtil {
return format.parse(String.valueOf(date)).getTime();
}
/**
* Java
* SimpleDateFormat"yyyy-MM-dd HH:mm:ss""1970-01-06 11:45:55"SimpleDateFormatparseDateDategetTime便
*
*
* @param args 使
* @throws ParseException 使SimpleDateFormatparseJava
*/
public static void main(String[] args) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
String time="1970-01-06 11:45:55";
Date date = format.parse(time);
System.out.print("Format To times:"+date.getTime());
}
}
}

@ -15,134 +15,112 @@ import java.text.SimpleDateFormat;
/**
* jackson
*/
// 使用lombok的@Slf4j注解用于自动生成日志相关的代码方便在类中记录各种操作相关的日志信息便于后续查看操作情况以及进行问题排查例如在进行对象序列化、反序列化操作出现问题时通过日志记录错误信息有助于定位和解决问题。
@Slf4j
public class JsonUtil {
// 创建一个ObjectMapper对象ObjectMapper是Jackson库中用于处理JSON数据与Java对象之间相互转换的核心类这里将其定义为静态成员变量方便在整个类的各个静态方法中共享使用避免重复创建对象提高效率。
private static ObjectMapper objectMapper = new ObjectMapper();
// 静态代码块在类加载时执行用于对ObjectMapper对象进行一系列的配置设置以满足特定的JSON处理需求确保在序列化和反序列化操作时按照期望的方式进行。
static {
// 设置序列化时包含所有字段即无论字段的值是否为null都将其列入进行转换默认情况下有些配置可能会忽略null值字段这里通过设置JsonSerialize.Inclusion.ALWAYS来确保所有字段都参与序列化使得转换后的JSON数据能完整反映Java对象的结构。
//所有字段都列入进行转换
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);
// 取消默认将日期类型转换为时间戳形式的行为改为按照指定的格式进行转换这样在处理包含日期字段的Java对象转换为JSON时日期会以更易读、符合业务需求的格式呈现而不是以时间戳的形式出现方便查看和使用。
//取消默认转换timestamp形式
objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
// 配置忽略空bean即没有属性值的Java对象转JSON时的错误避免在转换这样的对象时抛出异常使得即使对象为空也能正常进行序列化操作返回相应的JSON表示可能为空对象的JSON形式
objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);
//忽略空bean转json的错误
objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
// 统一设置日期的格式使用DateTimeUtil类中定义的标准格式"yyyy-MM-dd HH:mm:ss"),确保在整个应用中,涉及日期类型的序列化和反序列化操作都能按照这个统一的格式进行,保证日期数据的一致性和可读性。
objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
//统一时间的格式
objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));
// 配置忽略JSON数据中存在属性但对应的Java对象不存在该属性时的错误这样在进行反序列化操作时即使JSON数据包含一些Java对象中未定义的额外属性也不会抛出异常提高了对不同格式JSON数据的兼容性方便处理一些可能存在扩展属性的情况。
//忽略json存在属性但是java对象不存在属性的错误
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
}
/**
* JavaobjJSON便使
* nullnull
* null使ObjectMapperwriteValueAsStringJSONIOJSONlog.warnparse object to string errornull
*
* @param obj JSONJavaJSONObjectMapperJSON
* @param <T> 使
* @return JSONnullnullJSON
*
* @param obj
* @param <T>
* @return
*/
public static <T> String obj2String(T obj) {
if (obj == null) {
public static <T> String obj2String(T obj){
if(obj == null){
return null;
}
try {
return obj instanceof String? (String) obj : objectMapper.writeValueAsString(obj);
return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
} catch (IOException e) {
log.warn("parse object to string error", e);
log.warn("parse object to string error",e);
return null;
}
}
/**
* obj2StringJavaJSON便JSON使JSON便
* nullnullnull使ObjectMapperwriterWithDefaultPrettyPrinterJSONwriteValueAsStringJSONIOnull便
*
* @param obj JSONJavaJSON
* @param <T>
* @return JSONnullnullJSON便
* 便
* @param obj
* @param <T>
* @return
*/
public static <T> String obj2StringPretty(T obj) {
if (obj == null) {
public static <T> String obj2StringPretty(T obj){
if(obj == null){
return null;
}
try {
return obj instanceof String? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (IOException e) {
log.warn("parse object to string error", e);
log.warn("parse object to string error",e);
return null;
}
}
/**
* JSONstrclazzJava便JSONJava
* StringUtils.isEmptyclazznullnull
* String使ObjectMapperreadValueclazzJSONJavaIOJSONnullJava
*
* @param str JavaJSONObjectMapper
* @param clazz JavaClassUser.classJSONUser
* @param <T> Javaclazz
* @return JavanullnullJava便使
*
* @param str
* @param clazz
* @param <T>
* @return
*/
public static <T> T String2Obj(String str, Class<T> clazz) {
if (StringUtils.isEmpty(str) || clazz == null) {
public static <T> T String2Obj(String str,Class<T> clazz){
if(StringUtils.isEmpty(str) || clazz == null){
return null;
}
try {
return clazz.equals(String.class)? (T) str : objectMapper.readValue(str, clazz);
return clazz.equals(String.class)?(T)str:objectMapper.readValue(str,clazz);
} catch (IOException e) {
log.warn("parse string to obj error", e);
log.warn("parse string to obj error",e);
return null;
}
}
/**
* ClassTypeReference
* JSONStringUtils.isEmptyTypeReferencenullnull
* TypeReferenceTypeReferenceString使ObjectMapperreadValueTypeReferenceJSONJavaIOnull
*
* @param str JavaJSONTypeReference
* @param typeReference TypeReference便JSONJava
* @param <T> JavaTypeReference使
* @return JavatypeReferencenullnullJava使
*
* @param str
* @param typeReference
* @param <T>
* @return
*/
public static <T> T Str2Obj(String str, TypeReference typeReference) {
if (StringUtils.isEmpty(str) || typeReference == null) {
public static <T> T Str2Obj(String str, TypeReference typeReference){
if(StringUtils.isEmpty(str) || typeReference == null){
return null;
}
try {
return (T) (typeReference.getType().equals(String.class)? str : objectMapper.readValue(str, typeReference));
return (T) (typeReference.getType().equals(String.class)?str:objectMapper.readValue(str,typeReference));
} catch (IOException e) {
log.warn("parse string to obj error", e);
log.warn("parse string to obj error",e);
return null;
}
}
/**
* collectionClasselementClassesJavaType
* ObjectMappergetTypeFactory使constructParametricTypeJavaTypeJavaType
* 使ObjectMapperreadValueJavaTypeJSONJavaIOnull
*
* @param str JavaJSONJavaType
* @param collectionClass List.classSet.class
* @param elementClasses User.classAddress.class
* @param <T> JavaJavaType使
* @return JavanullJava便
*
* @param str
* @param collectionClass
* @param elementClasses
* @param <T>
* @return
*/
public static <T> T Str2Obj(String str, Class<?> collectionClass, Class<?>... elementClasses) {
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
public static <T> T Str2Obj(String str,Class<?> collectionClass,Class<?>... elementClasses){
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
try {
return objectMapper.readValue(str, javaType);
return objectMapper.readValue(str,javaType);
} catch (IOException e) {
log.warn("parse string to obj error", e);
log.warn("parse string to obj error",e);
return null;
}
}
}
}

@ -6,8 +6,6 @@ import java.security.MessageDigest;
* MD5
*/
public class MD5Util {
// 这个私有静态方法用于将字节数组转换为十六进制字符串表示形式。
// 它通过遍历字节数组中的每个字节调用byteToHexString方法将每个字节转换为对应的十六进制字符表示然后将这些字符依次追加到StringBuffer对象中最后返回拼接好的十六进制字符串结果该方法在后续的MD5编码过程中用于将字节形式的摘要结果转换为便于查看和使用的十六进制字符串形式。
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
@ -16,8 +14,6 @@ public class MD5Util {
return resultSb.toString();
}
// 这个私有静态方法用于将单个字节转换为十六进制字符串表示形式。
// 首先如果字节值为负数在Java中字节是有符号的范围是 -128 到 127通过加上256将其转换为无符号的等效值范围变为0到255然后分别计算出高4位和低4位对应的十六进制数字通过除以16取整得到高4位取余得到低4位最后从预定义的十六进制字符数组hexDigits中取出对应的字符并拼接起来返回从而实现将字节转换为十六进制字符串的功能。
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
@ -27,9 +23,37 @@ public class MD5Util {
return hexDigits[d1] + hexDigits[d2];
}
/**
* MD5MD5
*
* @param origin MD5MD5
* @param charsetname "utf-8"null使MD5MD5
* @return MD5
/**
* MD5
*
* @param origin
* @param charsetname
* @return
*/
private static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString.toUpperCase();
}
public static String MD5EncodeUtf8(String origin) {
//这里可以加盐
return MD5Encode(origin, "utf-8");
}
public static void main(String[] args) {
System.out.println(MD5EncodeUtf8("123456"));
}
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}

@ -14,29 +14,21 @@ import org.springframework.stereotype.Component;
* @CONTACT 317758022@qq.com
* @DESC zkcurator
*/
// 使用Spring框架的@Component注解将这个类标记为一个组件意味着该类会被Spring容器进行管理能够参与到依赖注入等Spring相关的功能中方便在其他需要使用此类实例的地方通过自动注入等方式获取实例实现不同组件之间的协作。
@Component
public class ZkClient {
// 通过Spring的依赖注入机制使用@Autowired注解自动注入Parameters类型的实例Parameters类应该是用于存储系统相关配置参数的类在这里主要是期望从中获取与Zookeeper连接相关的配置参数例如Zookeeper服务器的主机地址等信息以便后续构建Zookeeper客户端连接时使用。
@Autowired
private Parameters parameters;
// 使用Spring的@Bean注解该注解用于告诉Spring容器这个方法会返回一个对象这个对象会被Spring管理并注册到容器中其他组件可以通过依赖注入的方式获取这个对象在这里就是用于创建并返回一个CuratorFramework类型的Zookeeper客户端对象方便在整个应用中使用该客户端与Zookeeper服务器进行交互。
@Bean
public CuratorFramework getZkClient() {
// 使用CuratorFrameworkFactory的builder方法创建一个构建器对象CuratorFramework是用于操作Zookeeper的客户端框架通过构建器模式可以方便地配置客户端的各种参数如连接字符串、连接超时时间、重试策略等后续再基于这个构建器来构建出最终的客户端实例。
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
// 通过调用构建器的connectString方法传入从Parameters实例中获取的Zookeeper主机地址parameters.getZkHost()来设置要连接的Zookeeper服务器的地址信息这样客户端就能知道要连接到哪台Zookeeper服务器上。
public CuratorFramework getZkClient(){
CuratorFrameworkFactory.Builder builder= CuratorFrameworkFactory.builder()
.connectString(parameters.getZkHost())
// 通过调用构建器的connectionTimeoutMs方法设置连接超时时间为3000毫秒即如果在3秒内无法建立与Zookeeper服务器的连接则认为连接超时会触发相应的超时处理逻辑避免长时间等待导致程序阻塞等问题。
.connectionTimeoutMs(3000)
// 通过调用构建器的retryPolicy方法设置重试策略为RetryNTimes类型这里传入参数5和10表示当连接Zookeeper服务器出现问题时会尝试重试5次每次重试的间隔时间为10毫秒通过这种重试机制来增加连接成功的概率应对可能出现的临时性网络问题等情况。
.retryPolicy(new RetryNTimes(5, 10));
// 使用构建器的build方法构建出CuratorFramework类型的Zookeeper客户端对象这个对象封装了与Zookeeper服务器交互的各种功能例如创建节点、读取节点数据、监听节点变化等操作都可以通过这个客户端对象来实现。
CuratorFramework framework = builder.build();
// 调用构建好的Zookeeper客户端对象的start方法来启动客户端启动后客户端就会尝试按照配置的参数去连接Zookeeper服务器开始建立连接并准备进行后续的交互操作只有启动后客户端才能正常使用。
framework.start();
// 将启动后的Zookeeper客户端对象返回这样Spring容器就会将这个对象管理起来其他需要与Zookeeper进行交互的组件可以通过依赖注入的方式获取这个客户端对象进而使用其功能来操作Zookeeper。
return framework;
}
}

Loading…
Cancel
Save