up:: SpringBoot电商项目用户模块使用MD5对密码进行保护
说明:
(1) 登录的基本逻辑:【用户在前端输入用户名、密码】→【Controller获取到用户名和密码】→【调用Service中编写的login方法】→【然后,Service会去调用Mapper接口中定义的方法,这个方法是根据用户名和密码两个条件,去查询User】→【如果Service调用Mapper接口的方法后,查到了,就返回User对象;如果没查到,就抛出一个异常】→【自然,如果Service抛出了异常,Controller接到了这个异常后,也继续抛,自然我们前面编写的GlobalExceptionHandler会根据这个异常构建对应的ApiRestResponse】→【如果Service执行OK,Controller就会获取到查询的User,将这个对象保存到Session中,然后构建ApiRestResponse对象,返回】;
(2) 本篇博客需要注意的点:
● 如果Mapper接口中的方法不止一个,需要使用@Param注解;即,对于Mybatis来说,如果Mapper接口中的方法只有一个参数的话,是 可以 不用【@Param注解】注解的;但是,如果有多个参数的话,是一定要使用【@Param注解】注解的;否则,mapper.xml中的SQL语句在获取参数的时候,就会混乱;(即@Param注解的作用类似于:给其参数起个别名,在投入到SQL之前,最后归整一下)
● 一个新的开发习惯:先在实现类中编写方法实现,然后再在接口中反向生成方法声明;比如,本篇博客中,我们就心在UserServiceImpl实现类中,编写了login()方法的实现;然后,再在UserService接口中反向生成了login()方法的定义;
● 在登录的时候,不能的登录的原因有很多,如【用户名不存在,密码错误】等;出于对系统的保护,防止黑客窥探我们程序的细节,这些错误我们全部使用【密码错误】这一个去表征;
● 登录接口,需要我们返回登录用户的信息;但,记得要把密码password给清除掉;

0.登陆功能说明;
(1) 当某个用户登录后,是需要保存这个登陆状态的;只有保存了这个登陆状态,我们在后面进行如【添加商品到购物车】、【查看订单】等需要登录才能操作的操作时,才OK嘛;
(2) 在本项目中,我们把登陆状态,保存在session中;即,我们服务端把用户的登录信息保存在session中;即,一个用户登陆了系统,然后服务端把该用户的登陆信息保存在了session中,该用户登录之后,又来系统进行访问的话,就可以利用session把这个用户给识别出来;
1.在UserController类中,编写登陆方法;
/**
* 登录方法
* @param userName
* @param password
* @param session
* @return
*/
@PostMapping("/login")
@ResponseBody
public ApiRestResponse login(@RequestParam("userName") String userName, @RequestParam("password") String password, HttpSession session) throws ImoocMallException {
if (StringUtils.isEmpty(userName)) {//如果用户名为空,直接返回用户名不能为空的信息;
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_USER_NAME);
}
if (StringUtils.isEmpty(password)) {//如果密码为空,直接返回密码不能为空的信息;
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_PASSWORD);
}
User user = userService.login(userName, password);
user.setPassword(null);//返回用户信息时候,去掉密码
session.setAttribute(Constant.IMOOC_MALL_USER, user);
return ApiRestResponse.success(user);
}说明:
(1) url、请求方式、参数,要符合登陆接口的要求;

(2) 内容说明;

(3) 在把登陆的用户信息保存在Session中的时候,因为这个key可以看成是一个常量,所以,我们这个key也定义在了Constant类中;

(4) 有关Service中的login()登陆方法,在下一部分介绍;
2.在UserServiceImpl类中,编写login登陆方法,实现登陆逻辑;在UserService接口中,定义login登陆方法;
(1)在UserServiceImpl类中,编写login登陆方法;
/**
* 登录方法
* @param userName
* @param password
* @return
* @throws ImoocMallException
*/
@Override
public User login(String userName, String password) throws ImoocMallException {
String md5Password = null;
try {
md5Password = MD5Utils.getMD5String(password);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
User user = userMapper.selectLogin(userName, md5Password);
if (user == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_PASSWORD);
}
return user;
}(2)在UserService接口中,定义login登陆方法:一个新的开发习惯:我们可以,先在ServiceImpl实现类中,写对应的方法;然后,反向生成Service接口中的方法;
/**
* 登录方法
* @param userName
* @param password
* @return
* @throws ImoocMallException
*/
User login(String userName, String password) throws ImoocMallException;



以后,我们可以多使用这种【先在实现类中编写方法实现,然后再在接口中反向生成方法声明】的开发习惯;
说明:
(1) login方法说明;

(2) 至于Mapper接口中,【根据用户名和密码两个条件,查询User】的内容,在下部分介绍;
3.在UserMapper接口中,定义【根据用户名和密码两个条件,查询User的方法】;在UserMapper.xml中,编写对应的实现SQL;
(1)在UserMapper接口中,定义【根据用户名和密码,查询User的方法】:selectLogin()方法;
/**
* 登录时使用:根据用户名和密码两个条件,查询User
* @param userName
* @param password
* @return
*/
User selectLogin(@Param("userName") String userName,@Param("password")String password);说明;多参数sql语句查询使用@Param注解!!!
(2)在UserMapper.xml中,编写对应的实现SQL;
<select id="selectLogin" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from imooc_mall_user
where username=#{userName,jdbcType=VARCHAR}
and password=#{password};
</select>说明:
(1) 上一次在Mapper接口的方法中,使用【@Param注解】是在【OA系统开发请假申请Mapper层】;
(2) 对于Mybatis来说,如果Mapper接口中的方法只有一个参数的话,是 可以 不用【@Param注解】注解的;但是,如果有多个参数的话,是一定要使用【@Param注解】注解的;否则,mapper.xml中的SQL语句在获取参数的时候,就会混乱;(即@Param注解的作用类似于:给其参数起个别名,在投入到SQL之前,最后归整一下)
