/** 处理用户数据的业务层实现类 */
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
@Override
public void reg(User user) {
// 根据参数user对象获取注册的用户名
String username = user.getUsername();
// 调用持久层的User findByUsername(String username)方法,根据用户名查询用户数据
User result = userMapper.findByUsername(username);
// 判断查询结果是否不为null
if (result != null) {
// 是:表示用户名已被占用,则抛出UsernameDuplicateException异常
throw new UsernameDuplicatedException("尝试注册的用户名[" + username + "]已经被占用");
}
// 创建当前时间对象
Date now = new Date();
// 补全数据:加密后的密码,盐值就是一个随机的字符串
String salt = UUID.randomUUID().toString().toUpperCase();
String md5Password = getMd5Password(user.getPassword(), salt);
user.setPassword(md5Password);
// 补全数据:盐值
user.setSalt(salt);
// 补全数据:isDelete(0)
user.setIsDelete(0);
// 补全数据:4项日志属性
user.setCreatedUser(username);
user.setCreatedTime(now);
user.setModifiedUser(username);
user.setModifiedTime(now);
// 表示用户名没有被占用,则允许注册
// 调用持久层Integer insert(User user)方法,执行注册并获取返回值(受影响的行数)
Integer rows = userMapper.insert(user);
// 判断受影响的行数是否不为1
if (rows != 1) {
// 是:插入数据时出现某种错误,则抛出InsertException异常
throw new InsertException("添加用户数据出现未知错误,请联系系统管理员");
}
}
/**
* 执行密码加密
* @param password 原始密码
* @param salt 盐值
* @return 加密后的密文
*/
private String getMd5Password(String password, String salt) {
/*
* 加密规则:
* 1、无视原始密码的强度
* 2、使用UUID作为盐值,在原始密码的左右两侧拼接
* 3、循环加密3次
*/
for (int i = 0; i < 3; i++) {
password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()).toUpperCase();
}
return password;
}
拦截器:
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute("uid") == null) {
response.sendRedirect("/web/login.html");
return false;
}
return true;
}
}
** 注册处理器拦截器 */
@Configuration
public class LoginInterceptorConfigurer implements WebMvcConfigurer {
/** 拦截器配置 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建拦截器对象
HandlerInterceptor interceptor = new LoginInterceptor();
// 白名单
List<String> patterns = new ArrayList<String>();
patterns.add("/bootstrap3/**");
patterns.add("/css/**");
patterns.add("/images/**");
patterns.add("/js/**");
patterns.add("/web/register.html");
patterns.add("/web/login.html");
patterns.add("/web/index.html");
patterns.add("/web/product.html");
patterns.add("/users/reg");
patterns.add("/users/login");
patterns.add("/districts/**");
patterns.add("/products/**");
// 通过注册工具添加拦截器
registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(patterns);
监听器:防止同一用户重复登录
@RequestMapping("/checkLogin.do")
public String checkLogin(HttpSession session, String username, String password) {
System.out.println("checkLogin.do");
UserBean user=userService.login(username,password);
if(user!=null){//登录成功
//session.getServletContext()得到时application对象
ServletContext application=session.getServletContext();
Map<String, String> loginMap = (Map<String, String>)application.getAttribute("loginMap");
if(loginMap==null){
loginMap = new HashMap<>();
}
for(String key:loginMap.keySet()) {
if (user.getUsername().equals(key)) {
if(session.getId().equals(loginMap.get(key))) {
System.out.println(username+"在同一地点多次登录!");
}else{
System.out.println(username+"异地登录被拒绝!");
session.setAttribute("tip", "该用户已经异地登录!");
return "forward:/index.jsp";
}
}
}
loginMap.put(user.getUsername(),session.getId());
application.setAttribute("loginMap", loginMap);
session.setAttribute("username",user.getUsername());
System.out.println("登录成功!");
return "redirect:/index";
}else{
//登录失败
System.out.println("登录失败!");
session.setAttribute("tip","登录失败!");
return "forward:/index.jsp";
}
}
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
//在session销毁的时候 把loginMap中保存的键值对清除
String username = event.getSession().getAttribute("username").toString();
if(username!=null){
Map<String, String> loginMap = (Map<String, String>)event.getSession().getServletContext().getAttribute("loginMap");
loginMap.remove(username);
event.getSession().getServletContext().setAttribute("loginMap",loginMap);
System.out.println(username+"用户注销!");
}
}
}