SpringMVC拦截器案例:用户登录权限控制

本文最后更新于:2 年前

需求:用户没有登录的情况下,不能对后台菜单进行访问操作,点击菜单跳转到登录页面,只有用户登录
成功后才能进行后台功能的操作。

  1. 编写拦截器实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class PrivilgegInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //判断用户是否登录,本质是判断session中是否有user
    HttpSession session = request.getSession();
    User user = (User) session.getAttribute("user");
    if (user == null) {
    //没有登录,不放行
    response.sendRedirect(request.getContextPath()+"/login.jsp");
    return false;
    }
    //放行,访问目标资源
    return true;

    }
    }
  2. 在 spring-mvc 中进行配置权限拦截器:

    1
    2
    3
    4
    5
    6
    7
    <!--配置权限拦截器-->
    <mvc:interceptors>
    <mvc:interceptor>
    <mvc:mapping path="/**/"/>
    <bean class="cc.gaojie.interceptor.PrivilegeInterceptor"/>
    </mvc:interceptor>
    </mvc:interceptors>
  3. 此时点击用户管理后会自动跳转到登录页面:

  4. 在登录页面 login.jsp 中指定登录时要调用的方法(方法的虚拟映射地址)

    1
    2
    3
    4
    <form action="${pageContext.request.contextPath}/user/login"
    method="post">
    …………
    </form>
  5. 在 UserController 中编写利用 session 存储登录状态的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RequestMapping("/login")     //Restful风格参数
    public String login(String username, String password, HttpSession session){
    User user = userService.login(username,password);
    if (user != null) {
    //登录成功,将user存储到session中
    session.setAttribute("user",user);
    return "redirect:/index.jsp";
    }
    return "redirect:/login.jsp";
    }
  6. 在 UserService 中编写实现方法:

    1
    2
    3
    4
    5
    public interface UserService {

    User login(String username, String password);

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class UserServiceImpl implements UserService {

    private UserDao userDao;
    public void setUserDao(UserDao userDao) { this.userDao = userDao; }

    @Override
    public User login(String username, String password) {
    User user = userDao.findByUsernameAndPasssword(username,password);
    return user;
    }
    }
  7. 编写 dao 层接口及实现:

    1
    2
    3
    4
    5
    public interface UserDao {

    User findByUsernameAndPasssword(String username, String password);

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class UserDaoImpl implements UserDao {

    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; }


    @Override
    public User findByUsernameAndPasssword(String username, String password) {
    User user = jdbcTemplate.queryForObject("select * from sys_user where username = ? and password = ?", new BeanPropertyRowMapper<User>(User.class), username, password);
    return user;
    }
  8. 在 spring-mvc.xml 配置权限,放行登录操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!--配置权限拦截器-->
    <mvc:interceptors>
    <mvc:interceptor>
    <!--配置哪些资源拦截-->
    <mvc:mapping path="/**/"/>
    <!--配置哪些资源排除拦截-->
    <mvc:exclude-mapping path="/user/login"/>
    <bean class="cc.gaojie.interceptor.PrivilegeInterceptor"/>
    </mvc:interceptor>
    </mvc:interceptors>

    到处,用户登录权限控制的功能就实现了,当用户访问时,就可以达到如下效果:


存在的问题:当用户登录时输入错误密码后,浏览器会显示505页面报异常:

这是因为我们登录时在 dao 层使用的 queryForObject() 方法查询账号密码进行验证,当查询不到记录时该方法会报异常。

我们选择的解决方案是,把异常抛出到 service 层,进行 try…catch 处理,将异常转为 null (相当于没登录,继续让用户登录):

1
2
3
4
5
6
7
8
9
10
11
public class UserDaoImpl implements UserDao {

private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; }

@Override
public User findByUsernameAndPassword(String username, String password) throws EmptyResultDataAccessException {
User user = jdbcTemplate.queryForObject("select * from sys_user where username = ? and password = ?", new BeanPropertyRowMapper<User>(User.class), username, password);
return user;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserServiceImpl implements UserService {

private UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao; }

@Override
public User login(String username, String password) {
try {
User user = userDao.findByUsernameAndPassword(username,password);
return user;
} catch (EmptyResultDataAccessException e) {
return null;
}

}