拦截器实现登录拦截
拦截器
一般登录的时候需要拦截,如果没有登录,则不能访问系统的内部资源
拦截是根据session进行拦截的.
在登录里面需要先将session通过cookie发给浏览器
// 把用户信息写入session, 拦截器根据session来判定用户是否登录
session.setAttribute("user", user);
//登录成功, 别用重定向, 重定向是又向服务器重新发送请求, session会失效
实现拦截器需要实现HandlerInterceptor接口,重写preHandle方法
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求地址: " + request.getRequestURI());
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
// 如果涩ssion中存在user, 说明已经登录
if (user != null) {
// 已经登陆
return true;
} else {
// 未登录
// 如果说你有应用名, 这个路径必须加上应用名
// 这样会比较麻烦, 你可以获取应用名, 跟jsp的类似,嗯嗯
// ${pageContext.request.contextPath} 和 request.getContextPath() 等效
response.sendRedirect(request.getContextPath() + "/user/toLogin");
return false;
}
}
然后再mvc层的xml中配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<!--一个拦截器
如果有多个拦截器拦截器, 有不同的处理方法, 可以写多个<mvc:interceptor>-->
<mvc:interceptor>
<!--拦截所有请求 /**-->
<mvc:mapping path="/**"/>
<!--允许通过的请求, 这里不考虑应用名,登录提交的请求
<mvc:exclude-mapping path="/toLogin"/>可以写多个
-->
<mvc:exclude-mapping path="/user/toLogin"/>
<mvc:exclude-mapping path="/user/login"/>
<!--绑定拦截器-->
<bean class="com.tedu.controller.LoginInter"/>
</mvc:interceptor>
</mvc:interceptors>
配置拦截器于各层
在util或者其他包下,创建拦截器类LoginInter,实现HandlerInterceptor接口
package com.tedu.controller;
import com.tedu.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
// 拦截器要实现这个接口, 然后再xml中进行配置
public class LoginInter implements HandlerInterceptor {
/**
* 起到主要拦截作用, 然会true表示通过
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求地址: " + request.getRequestURI());
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
// 如果涩ssion中存在user, 说明已经登录
if (user != null) {
// 已经登陆
return true;
} else {
// 未登录
// 如果说你有应用名, 这个路径必须加上应用名
// ${pageContext.request.contextPath} 和 request.getContextPath() 等效
response.sendRedirect(request.getContextPath() + "/user/toLogin");
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
Controller层需要绑定session,拦截器根据session来绑定用户是否登录
@Controller
// 这里如果写的话, 最好写requestMapping, 否则这个controller只能处理一种提交方式的请求明白
@RequestMapping("/user")
public class LoginController {
// 你查询的时候应该是根据用户名查询
// 使用这个注解效率会高一丢丢,或者post的
//调service层
@Autowired
@Qualifier("UserServiceImpl") // 这个注解可写可不写
private UserServiceImpl userService;
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
@RequestMapping("/login") // 你访问这个url, 并没有传值, 所以一直重定向
public String login(String username, String password, Model model, HttpSession session){
User user = userService.findOneByName(username);
if (user==null){
//说明用户不存在, 重定向到登录界面
model.addAttribute("msg", "用户不存在!");
return "login";
}else if (user.getPassword().equals(password)){
// 把用户信息写入session, 拦截器根据session来判定用户是否登录
session.setAttribute("user", user);
// 登录成功, 别用重定向, 重定向是又向服务器重新发送请求, session会失效
return "forward:/book/allBook"; // return的字符串是jsp的名, 不是请求的url
} else {
// 密码错误
model.addAttribute("msg","密码错误!");
return "login";
}
}
资源文件的配置
在mvc层配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<!--一个拦截器
如果有多个拦截器拦截器, 有不同的处理方法, 可以写多个<mvc:interceptor>-->
<mvc:interceptor>
<!--拦截所有请求 /**-->
<mvc:mapping path="/**"/>
<!--允许通过的请求, 这里不考虑应用名
<mvc:exclude-mapping path="/toLogin"/>可以写多个
-->
<mvc:exclude-mapping path="/user/toLogin"/>
<mvc:exclude-mapping path="/user/login"/>
<!--绑定拦截器-->
<bean class="com.tedu.controller.LoginInter"/>
</mvc:interceptor>
</mvc:interceptors>