2.用户的登录和修改密码
1.总结:昨天主要是实现了用户的登录和密码修改,在进行登录的时候,首先使用mapper中的方法查询用户是否为空以及是否已被逻辑删除
然后通过传入的密码参数和盐值Md5加密与原来存在的密码进行对比,没问题后再创建一个user对象,设置一些属性返回;在项目中
会出现uid和username频繁使用的问题,此时我们在UserController的login方法中将登录用户的uid和username存入到session中,再在
BaseController中定义一个final的从HttpSession中获取uid和username的两个方法;final修饰的方法只可继承不可重写。
在密码修改中,首先在mapper中定义updatePasswordByUid和findByUid来年各个方法,再在IUserService接口中定义changePassword
()方法通过uid,username,oldPassword,以及newPassword来实现密码修改;在service实现类中,首先是使用findByUid()方法查询到
登录用户信息,判断登录信息是否存在以及是否被逻辑删除,再通过oldPassword以及盐值对比原来的密码,成功就添加新的密码与盐值
MD5结合,再根据uid,newPassword,modifiedUser以及ModifiedTime来进行密码修改
用户登录
service
User login(String username, String password);
serviceImpl
@Override public User login(String username, String password) { //调用userMapper的findByUsername()方法,根据username查询用户信息 User result = userMapper.findByUsername(username); //判断查询结果是否为空,是:抛出UserNotFoundException //判断查询结果中的isDelete是否为1,是:抛出UserNotFoundException异常 if (result == null ){ throw new UserNotFoundException("用户没找到!"); } if(result.getIsDelete() == 1){ throw new UserNotFoundException("用户没找到!"); } //从查询结果中获取盐值 //调用getMd5Password()方法,将password饿salt结合起来加密 String MD5PassWord = getMd5Password(password, result.getSalt()); if (!MD5PassWord.equals(result.getPassword())){ throw new PasswordNotMatchException("用户名密码错误!"); } //创建新的User对象,将查询的uid,username,avatar封装到新的user对象中,返回新的对象 //注意:为什么不直接返回整个查询到的用户信息呢,实现数据的有效性(只取所需) User user = new User(); user.setUid(result.getUid()); user.setUsername(result.getUsername()); user.setAvatar(result.getAvatar()); return user; }
BaseController
public class BaseController { public static final int OK = 200; //统一处理方法抛出的异常,此注解表示专门处理这个类的异常 //注意:不要使用相同的注解参数,例如:Throwable e @ExceptionHandler(ServiceException.class) public JsonResult<Void>handleException(Throwable e){ JsonResult<Void> result = new JsonResult<>(); if (e instanceof UsernameDuplicateException){ result.setState(400); result.setMessage("用户名已存在!"); }else if(e instanceof UserNotFoundException){ result.setState(401); result.setMessage("用户名未找到!"); }else if(e instanceof PasswordNotMatchException){ result.setState(402); result.setMessage("密码不匹配!"); }else if(e instanceof InsertException){ result.setState(500); result.setMessage("插入用户数据出现未知错误!"); }return result; } /** * 从HttpSession对象中获取uid * @param session HttpSession对象 * @return 当前登录用户id */ protected final Integer getUidFromSession(HttpSession session){ return Integer.valueOf(session.getAttribute("uid").toString()); } /** * 从HttpSession对象中获取username * @param session HttpSession对象 * @return 当前登录用户的username */ protected final String getUsernameFromSession(HttpSession session){ return session.getAttribute("username").toString(); } }
UserController
@RequestMapping("/login") public JsonResult<User> login(String username, String password, HttpSession session){ //调用业务对象方法执行登录,并获取返回值 User user = userService.login(username, password); //登录成功后,将uid和username存入到HttpSession中 session.setAttribute("uid", user.getUid()); session.setAttribute("username", user.getUsername()); //将以上返回值和状态码OK封装到相应结果中并返回 return new JsonResult<User>(OK, user); }
修改密码
mapper
//@Param作用:给参数命名,命名后根据名字得到参数值,正确地将参数传入SQL Integer updatePasswordByUid(@Param("uid") Integer uid, @Param("password") String password, @Param("modifiedUser") String modifiedUser, @Param("modifiedTime")Date modifiedTime); User findByUid(Integer uid); Integer updateInfoByUid(User user);
<update id="updatePasswordByUid">
update
store.t_user
set
password = #{password},
modified_user = #{modifiedUser},
modified_time = #{modifiedTime}
where
uid = #{uid}
</update>
<!--uid = #{uid}q前面是是字段值,后面是属性值-->
<select id="findByUid" resultMap="UserEntityMap">
select
*
from
store.t_user
where
uid = #{uid}
</select>
service
void changePassword(Integer uid, String username, String oldPassword, String newPassword); /** * 根据uid获取当前登录用户信息 * @param uid * @return */ User getByUid(Integer uid);
serviceImpl
@Override public void changePassword(Integer uid, String username, String oldPassword, String newPassword) { //调用UserMapper的findByUid()方法,根据uid查询用户数据 User result = userMapper.findByUid(uid); if (result == null){ throw new UserNotFoundException("用户不存在!"); } if(result.getIsDelete() == 1){ throw new UserNotFoundException("用户不存在!"); } //从查询结果中取出盐值 //将参数oldPassword结合盐值加密,得到oldMd5Password //判断查询结果中的password()与oldMd5Password是否不一致 //不一致就抛出PasswordNotMatchException异常 String oldMd5Password = getMd5Password(oldPassword, result.getSalt()); if (!result.getPassword().equals(oldMd5Password)){ throw new PasswordNotMatchException("密码不匹配!"); } String newMd5Password = getMd5Password(newPassword, result.getSalt()); Date now = new Date(); Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, now); if (rows != 1){ throw new UpdateException("更新用户数据异常!"); } }
UserController
@RequestMapping("/change_password") //在这里报错为空是因为并还没有登录,所以导致的 //lower密码还是888888 public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session){ //调用session.getAttribute("")获取uid和username Integer uid = getUidFromSession(session); String username = getUsernameFromSession(session); //调用业务对象执行修改密码 userService.changePassword(uid, username, oldPassword, newPassword); return new JsonResult<Void>(OK); }
一定要先登录再修改密码,因为uid和username是在登录之后存入session的
2.反思:JDK(java development kit java开发工具包)包含JRE(java Runtime environment java运行时环境),JDK中有一个jre目录,包含bin(JVM)和lib(JVM所需工具包)
=和equals区别:对于基本类型==比较的值,对于引用类型==比较的地址,equals不能比较基本类型,当equals没有被重写相当于==,被重写比较的对象内容
final可以修饰基本数据类型,定位常量不可被修改,修饰引用类型值可变地址不可变,修改类的成员变量要立刻赋值,修饰方法不可重写可继承,修饰类不可继承(String类)
Math.round():向上取整(11.3->12),向下取整(11.3->11),四舍五入(加0.5向下取整)(11.3->11.8->11)
String是引用类型,八种基本数据类型:byte,short,int,long,char,double ,float,boolean
还是要一边背面试题一边做项目,一天记五道基础面试题,一边做项目,两者之间相辅相成,不管对基础还是对项目都有互帮互利的效果,上面项目主要的收获是判断用户是否存在以及
是否逻辑删除,还有就是在登录的时候将uid和username存入session,再就是在BaseController中提取异常以及定义从session中获取uid和username
3.复盘:回顾电脑商城里面的用户注册,之前的单点登录也要偶尔观看和思考,为什么这么写,自己是否还有新的东西融入进去