接下的文章是用户的登录,退出,注册以及查看用户信息功能,因为需要涉及的代码有好多个部分包括controller层,Service层,Dao层,sql语句的编写,service接口的声明和实现,为了让文章看起来尽量的浓缩,篇幅不宜过长,大家就跟着我的思路从controller层开始-调用-》ServiceImpl层-调用-》Dao层-mappper.xml完成SQL的编写-》这样一个简单的逻辑来完成。
首先User模块的Controller登场:
@Controller
@RequestMapping("/user/")
public class UserController {
@Autowired
private IUserService iUserService;
/**
* 用户登录
* @param username
* @param password
* @param session
* @return
*/
@RequestMapping(value = "login.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> login(String username, String password, HttpSession session){
ServerResponse<User> response = iUserService.login(username,password);
if(response.isSuccess()){
session.setAttribute(Const.CURRENT_USER,response.getData());
}
return response;
}
@RequestMapping(value = "logout.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<String> logout(HttpSession session){
session.removeAttribute(Const.CURRENT_USER);
return ServerResponse.createBySuccess();
}
@RequestMapping(value = "register.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<String> register(User user){
return iUserService.register(user);
}
/**
* 用户校验
* @param str 校验类型 邮箱&用户名
* @param type 枚举类型常量进行判断
* @return
*/
@RequestMapping(value = "check_valid.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<String> checkValid(String str,String type){
return iUserService.checkValid(str,type);
}
/**
* 获取用户信息
* @param session
* @return 通过session获取登录用户的信息
*/
@RequestMapping(value = "get_user_info.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> getUserInfo(HttpSession session){
User user = (User) session.getAttribute(Const.CURRENT_USER);
if(user != null){
return ServerResponse.createBySuccess(user);
}
return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息");
}
其中用户注册信息的时候密码是加密后存在数据库的,并不是单纯明文密码,这样很不安全,在注册时候到库中校验用户名的账号和密码是否已经存在,密码采用的是MD5加密的方式,额外的增加了salt盐值。
Service层实现过程如下:
@Service("iUserService")
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
/**
* 用户登录
* @param username 账户
* @param password 密码
* @return
*/
@Override
public ServerResponse<User> login(String username, String password) {
int resultCount = userMapper.checkUsername(username);
if(resultCount == 0 ){
return ServerResponse.createByErrorMessage("用户名不存在");
}
// 因为系统使用的密码是加密的 所以登录前先把密码加密后在登录
String md5Password = MD5Util.MD5EncodeUtf8(password);
User user = userMapper.selectLogin(username,md5Password);
if(user == null){
return ServerResponse.createByErrorMessage("密码错误");
}
user.setPassword(org.apache.commons.lang3.StringUtils.EMPTY);
return ServerResponse.createBySuccess("登录成功",user);
}
/**
* 用户注册
* @param user
* @return
*/
public ServerResponse<String> register(User user){
// 校验用户是否存在
ServerResponse validResponse = this.checkValid(user.getUsername(),Const.USERNAME);
if(!validResponse.isSuccess()){
return validResponse;
}
// 校验邮箱是否存在
validResponse = this.checkValid(user.getEmail(),Const.EMAIL);
if(!validResponse.isSuccess()){
return validResponse;
}
// 默认设置登录的用户为 普通角色
user.setRole(Const.Role.ROLE_CUSTOMER);
//MD5加密
user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
int resultCount = userMapper.insert(user);
if(resultCount == 0){
return ServerResponse.createByErrorMessage("注册失败");
}
return ServerResponse.createBySuccessMessage("注册成功");
}
/**
* 用户邮箱和用户名校验
* @param str
* @param type
* @return
*/
public ServerResponse<String> checkValid(String str,String type){
if(org.apache.commons.lang3.StringUtils.isNotBlank(type)){
//开始校验
if(Const.USERNAME.equals(type)){
int resultCount = userMapper.checkUsername(str);
if(resultCount > 0 ){
return ServerResponse.createByErrorMessage("用户名已存在");
}
}
if(Const.EMAIL.equals(type)){
int resultCount = userMapper.checkEmail(str);
if(resultCount > 0 ){
return ServerResponse.createByErrorMessage("email已存在");
}
}
}else{
return ServerResponse.createByErrorMessage("参数错误");
}
return ServerResponse.createBySuccessMessage("校验成功");
}
Dao层主要sql语句:
// 用户注册sql
<insert id="insert" parameterType="com.mmall.pojo.User" >
insert into mmall_user (id, username, password,
email, phone, question,
answer, role, create_time,
update_time)
values
(#{id,jdbcType=INTEGER},
#{username,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR},
#{email,jdbcType=VARCHAR},
#{phone,jdbcType=VARCHAR},
#{question,jdbcType=VARCHAR},
#{answer,jdbcType=VARCHAR},
#{role,jdbcType=INTEGER},
now(),now())
</insert>
// 校验用户名
<select id="checkUsername" resultType="int" parameterType="string" >
select count(1) from mmall_user
where username = #{username}
</select>
// 校验email
<select id="checkEmail" resultType="int" parameterType="string" >
select count(1) from mmall_user
where email = #{email}
</select>
// 校验账户和密码 开始登录
<select id="selectLogin" resultMap="BaseResultMap" parameterType="map">
SELECT
-- *???//这样真的好么?答案就是,这样不好.
<include refid="Base_Column_List" />
from mmall_user
where username = #{username}
and password = #{password}
</select>
大家可以对照这看,且把三层之间的调用关系和逻辑关系弄清楚,然后结合我上一个篇文章的高可复用的服务器响应端类一起总结一下,下一篇我会介绍如何在登录前忘记密码操作和登录后密码修改操作,如果大家有什么不明白或者还需要哪些地方在写详细一点,我会按照大家要求来修改的,大家加油奥。