pull/4/head
zhouyu 9 months ago
parent db1c675115
commit 4e668b56a5

@ -29,215 +29,189 @@ import javax.servlet.http.HttpSession;
*/
//TODO 先全部开放GET请求
// 使用@RequestMapping注解将该类下所有的请求处理方法的请求路径都映射到以"/user"开头的路径下,
// 这样便于对用户相关的接口进行统一的路径管理使得接口的结构更加清晰符合RESTful风格的接口设计规范。
@RequestMapping("user")
// @RestController注解是一个组合注解相当于同时使用了@Controller和@ResponseBody注解。
// 表示这个类是一个Spring MVC的控制器类并且类中所有方法的返回值都会直接作为响应体ResponseBody返回给客户端
// 通常返回的数据格式为JSON等方便与前端进行数据交互处理客户端发送的关于用户相关的各种请求。
@RestController
// 使用lombok的@Slf4j注解用于自动生成日志记录相关的代码方便在类中的各个方法执行过程中记录日志信息
// 比如记录用户操作的相关情况、接口调用的状态等,有助于后续进行问题排查、系统监控以及数据分析等工作。
@Slf4j
// 表示标识这个类是swagger的资源
// @Api注解用于标识这个类是Swagger的资源在Swagger生成的接口文档中对这个控制器类进行描述。
// 通过设置value属性指定类在文档中的显示名称tags属性设置相关的标签便于对用户服务相关的接口在文档中进行分类展示
// 让接口的使用者(如前端开发人员、测试人员等)能够直观地了解接口所属的功能模块以及大致用途等信息。
@Api(value = "UserController", tags = {"用户服务接口"})
public class UserController {
// 通过Spring的依赖注入机制使用@Autowired注解自动注入IUserService类型的实例。
// IUserService应该是一个定义了与用户业务逻辑相关操作的接口其具体的实现类由Spring容器根据配置进行实例化并注入到此处。
// 通过这个接口可以调用诸如用户登录、注册、信息查询、修改等各种业务方法,以此实现具体的用户相关功能处理。
@Autowired
private IUserService userService;
// 同样使用@Autowired注解注入CommonCacheUtil类型的实例CommonCacheUtil类通常是用于缓存操作的工具类
// 在这里主要负责与Redis等缓存系统进行交互例如在用户登录后将用户信息缓存到Redis中或者从Redis中获取缓存的用户信息等操作
// 方便对用户相关的数据进行缓存管理,从而提高系统的性能,减少对数据库的频繁访问,提升数据获取的效率。
@Autowired
private CommonCacheUtil commonCacheUtil;
/**
* cookieredis
* key
* CookieRedis
*
* 访keyCookie
* 访
*
* @param session HttpSession
* sessionIdCookieRedis便
* @param response HttpServletResponseCookie
* 便
* @param username
*
* @param password
* @return ServerResponse<UserResVO>ServerResponse
* isSuccessUserResVO
* 便
*/
@ApiOperation(value="用户登陆", notes="输入用户名,密码,不能为空")
@ApiOperation(value = "用户登陆", notes = "输入用户名,密码,不能为空")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
@ApiImplicitParam(name = "password", value = "用户密码", required = true, dataType = "String")
})
@RequestMapping("/login.do")
public ServerResponse<UserResVO> login(HttpSession session, HttpServletResponse response, String username, String password){
log.info("【用户{}开始登陆】",username);
ServerResponse<UserResVO> userVOServerResponse = userService.login(username,password);
if(userVOServerResponse.isSuccess()){
//登陆成功那么需要在redis中存储并且将代表用户的sessionId写到前端浏览器的cookie中
log.info("【用户{}cookie开始写入】",username);
CookieUtil.writeLoginToken(response,session.getId());
//写到redis中将用户信息序列化设置过期时间为30分钟
log.info("【用户{}redis开始写入】",username);
public ServerResponse<UserResVO> login(HttpSession session, HttpServletResponse response, String username, String password) {
// 使用日志记录用户开始登录的信息,通过占位符{}的方式将用户名动态地记录到日志中,方便后续查看具体是哪个用户在什么时间发起了登录请求,
// 有助于排查登录相关的问题,例如某个用户频繁登录失败等情况时,可以通过日志分析原因。
log.info("【用户{}开始登陆】", username);
// 调用userService的login方法传入用户名和密码参数由userService的具体实现类来执行用户登录验证等相关的业务逻辑处理
// 例如可能会在数据库中查询用户信息验证用户名和密码是否匹配等操作最终返回一个ServerResponse<UserResVO>类型的对象,
// 包含了登录操作的结果以及登录成功后对应的用户相关信息(如果登录成功)。
ServerResponse<UserResVO> userVOServerResponse = userService.login(username, password);
if (userVOServerResponse.isSuccess()) {
// 如果登录成功那么需要将用户的登录状态信息存储到Redis中并且把代表用户的sessionId写到前端浏览器的Cookie中
// 这样后续用户访问其他页面时服务器可以通过验证Cookie中的sessionId以及Redis中的缓存信息来确认用户的登录状态。
log.info("【用户{}cookie开始写入】", username);
// 调用CookieUtil工具类的writeLoginToken方法将sessionId写入到响应的Cookie中传递给客户端浏览器保存
// 使得浏览器在后续的请求中会自动带上这个Cookie方便服务器识别用户身份。
CookieUtil.writeLoginToken(response, session.getId());
// 调用commonCacheUtil的cacheNxExpire方法先将用户信息通过JsonUtil的obj2String方法序列化为JSON字符串格式
// 然后将其存储到Redis中并设置过期时间为30分钟通过Constants.RedisCacheExtime.REDIS_SESSION_EXTIME来指定
// 这样可以在一定时间内缓存用户信息,避免频繁查询数据库获取相同的用户信息,提高系统性能,同时在过期后自动清除缓存数据,保证数据的时效性。
log.info("【用户{}redis开始写入】", username);
commonCacheUtil.cacheNxExpire(session.getId(), JsonUtil.obj2String(userVOServerResponse.getData()), Constants.RedisCacheExtime.REDIS_SESSION_EXTIME);
}
log.info("【用户{}登陆成功】",username);
// 使用日志记录用户登录成功的信息,同样通过占位符记录用户名,方便后续统计登录情况、排查登录相关问题等,
// 例如可以统计每日登录成功的用户数量等信息,通过日志进行辅助分析。
log.info("【用户{}登陆成功】", username);
return userVOServerResponse;
}
/**
*
* 使
* 使
*
* @param user User
*
* @return ServerResponse
* 便
*/
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@ApiOperation(value = "创建用户", notes = "根据User对象创建用户")
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
@RequestMapping("/register.do")
public ServerResponse register(User user){
public ServerResponse register(User user) {
log.info("【开始注册】");
//这里模拟高并发的注册场景,防止用户名字注册重复,所以需要加上分布式锁
// 在这里模拟高并发的注册场景,由于在多用户同时进行注册操作时,可能会出现并发访问导致对数据库中用户名或邮箱唯一性验证出现问题,进而造成重复注册的情况,
// 所以需要使用分布式锁来保证关键操作(如验证用户名和邮箱的唯一性以及向数据库中插入新用户记录等操作)的原子性,避免并发冲突。
// 调用userService的register方法由其具体实现类来执行用户注册相关的业务逻辑例如验证用户输入信息的合法性、检查用户名和邮箱是否重复、将新用户信息插入数据库等操作
// 最终返回一个ServerResponse类型的对象包含注册结果以及相关的提示信息等内容。
ServerResponse response = userService.register(user);
log.info("【用户注册成功】");
return response;
}
/**
*
* 使
*
*
* @param str
* type
* @param type strConstants
*
* @return ServerResponse
* 便
*/
@ApiOperation(value="验证用户名和邮箱是否重复", notes="用户名和邮箱都不能用已经存在的")
@ApiOperation(value = "验证用户名和邮箱是否重复", notes = "用户名和邮箱都不能用已经存在的")
@ApiImplicitParams({
@ApiImplicitParam(name = "str", value = "输入参数", required = true, dataType = "String"),
@ApiImplicitParam(name = "type", value = "参数类型", required = true, dataType = "String")
})
@RequestMapping("/check_valid.do")
public ServerResponse checkValid(@RequestParam("str") String str,
@RequestParam("type") String type){
@RequestParam("type") String type) {
log.info("【开始验证用户名和邮箱是否重复】");
ServerResponse response = userService.checkValid(str,type);
ServerResponse response = userService.checkValid(str, type);
return response;
}
/**
*
* cookieoursnai.cnhosts127.0.0.1 oursnail.cn
* loginGEThttp://oursnail.cn:8081/user/login.do?username=admin&password=123456
* tokenhttp://oursnail.cn:8081/user/get_user_info.do
* Cookie"oursnai.cn"
* hosts"127.0.0.1 oursnail.cn"使访Cookie
* loginGETPOST便
* http://oursnail.cn:8081/user/login.do?username=admin&password=123456进行登录操作获取到登录状态的Cookie信息后
* http://oursnail.cn:8081/user/get_user_info.do来请求这个获取用户信息的接口否则可能因为域名不匹配等原因无法获取到代表登录状态的token进而不能获取用户信息。
*
*
* @param request HttpServletRequest
* Cookie便token
* @return ServerResponse
* 便
*/
@ApiOperation(value="获取用户个人信息", notes="登陆状态下获取")
@ApiOperation(value = "获取用户个人信息", notes = "登陆状态下获取")
@RequestMapping("/get_user_info.do")
public ServerResponse getUserInfo(HttpServletRequest request){
public ServerResponse getUserInfo(HttpServletRequest request) {
// 调用CookieUtil工具类的readLoginToken方法从请求对象中读取代表登录状态的token该token存储在Cookie中
// 如果能够读取到则说明用户可能处于登录状态,若读取不到则表示用户未登录,后续需要进行相应的处理。
String loginToken = CookieUtil.readLoginToken(request);
if(StringUtils.isEmpty(loginToken)){
if (StringUtils.isEmpty(loginToken)) {
log.info("【用户未登录,无法获取当前用户信息】");
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
// 调用commonCacheUtil的getCacheValue方法根据读取到的登录token从缓存如Redis中获取对应的用户信息字符串
// 如果获取到的用户信息字符串为null则可能是缓存过期或者用户未登录等情况同样需要进行相应的处理。
String userStr = commonCacheUtil.getCacheValue(loginToken);
if(userStr == null){
if (userStr == null) {
log.info("【用户未登录,无法获取当前用户信息】");
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
User currentUser = JsonUtil.Str2Obj(userStr,User.class);
// 调用JsonUtil的Str2Obj方法将从缓存中获取到的用户信息字符串反序列化为User类型的对象以便后续进行业务逻辑处理
// 例如可以调用userService的相关方法进一步获取数据库中的详细用户信息等操作。
User currentUser = JsonUtil.Str2Obj(userStr, User.class);
UserResVO userResVO = userService.getUserInfoFromDB(currentUser.getId());
return ServerResponse.createBySuccess("登陆用户获取自身信息成功",userResVO);
return ServerResponse.createBySuccess("登陆用户获取自身信息成功", userResVO);
}
/**
*
*
* 便
*
* @param username
*
* @return ServerResponse
* 便
*/
@ApiOperation(value="根据用户名去拿到对应的问题", notes="忘记密码时首先根据用户名去获取设置的问题")
@ApiOperation(value = "根据用户名去拿到对应的问题", notes = "忘记密码时首先根据用户名去获取设置的问题")
@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String")
@RequestMapping("/forget_get_question.do")
public ServerResponse forgetGetQuestion(String username){
log.info("【用户{}忘记密码,点击忘记密码输入用户名】",username);
public ServerResponse forgetGetQuestion(String username) {
log.info("【用户{}忘记密码,点击忘记密码输入用户名】", username);
ServerResponse response = userService.getQuestionByUsername(username);
return response;
}
/**
*
*/
@ApiOperation(value="校验答案是否正确", notes="忘记密码时输入正确的用户名之后就可以获取到问题,此时就可以输入答案")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
@ApiImplicitParam(name = "question", value = "设置的问题", required = true, dataType = "String"),
@ApiImplicitParam(name = "answer", value = "提交的答案", required = true, dataType = "String")
})
@RequestMapping("/forget_check_answer.do")
public ServerResponse forgetCheckAnswer(String username,String question,String answer){
log.info("【用户{}忘记密码,提交问题答案】",username);
ServerResponse response = userService.checkAnswer(username,question,answer);
return response;
}
/**
*
*/
@ApiOperation(value="忘记密码的重置密码", notes="输入新的密码要进行token的校验")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
@ApiImplicitParam(name = "passwordNew", value = "新密码", required = true, dataType = "String"),
@ApiImplicitParam(name = "forgetToken", value = "前端保存的token", required = true, dataType = "String")
})
@RequestMapping("/forget_reset_password.do")
public ServerResponse forgetResetPasswd(String username,String passwordNew,String forgetToken){
log.info("【用户{}忘记密码,输入新密码】",username);
ServerResponse response = userService.forgetResetPasswd(username,passwordNew,forgetToken);
return response;
}
/**
*
*/
@ApiOperation(value="登陆状态的重置密码", notes="登陆的时候只需要输入老的密码和新密码即可")
@ApiImplicitParams({
@ApiImplicitParam(name = "passwordOld", value = "老密码", required = true, dataType = "String"),
@ApiImplicitParam(name = "passwordNew", value = "新密码", required = true, dataType = "String")
})
@RequestMapping("/reset_password.do")
public ServerResponse resetPasswd(String passwordOld,String passwordNew,HttpServletRequest request){
//1.读取cookie
String loginToken = CookieUtil.readLoginToken(request);
if(StringUtils.isEmpty(loginToken)){
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
//2.从redis中获取用户信息
String userStr = commonCacheUtil.getCacheValue(loginToken);
if(userStr == null){
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
User currentUser = JsonUtil.Str2Obj(userStr,User.class);
log.info("【用户{}重置密码】",currentUser);
ServerResponse response = userService.resetPasswd(passwordOld,passwordNew,currentUser.getId());
return response;
}
/**
*
*/
@ApiOperation(value="更新当前登陆用户信息", notes="更新用户信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "email", value = "邮箱", required = true, dataType = "String"),
@ApiImplicitParam(name = "phone", value = "电话", required = true, dataType = "String"),
@ApiImplicitParam(name = "question", value = "问题", required = true, dataType = "String"),
@ApiImplicitParam(name = "answer", value = "答案", required = true, dataType = "String")
})
@RequestMapping("/update_information.do")
public ServerResponse updateInformation(String email,String phone,String question,String answer,HttpServletRequest request){
//1.读取cookie
String loginToken = CookieUtil.readLoginToken(request);
if(StringUtils.isEmpty(loginToken)){
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
//2.从redis中获取用户信息
String userStr = commonCacheUtil.getCacheValue(loginToken);
if(userStr == null){
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户信息");
}
User currentUser = JsonUtil.Str2Obj(userStr,User.class);
ServerResponse response = userService.updateInfomation(email,phone,question,answer,currentUser.getId());
return response;
}
/**
* ,cookieredis
*/
@ApiOperation(value="登出", notes="退出登陆删除cookie和redis缓存")
@RequestMapping("/logout.do")
public ServerResponse logout(HttpServletRequest request,HttpServletResponse response){
log.info("【用户删除cookie】");
//1.删除cookie
String loginToken = CookieUtil.readLoginToken(request);
CookieUtil.delLoginToken(request,response);
log.info("【用户删除redis缓存】");
//2.删除redis中缓存记录
commonCacheUtil.delKey(loginToken);
return ServerResponse.createBySuccess();
}
}
/**
*
*
*
*
* @
Loading…
Cancel
Save