第三章:SpringMVC拦截器
OVERVIEW
一、SpringMVC拦截器
SpringMVC中的拦截器类似于Srevlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
将拦截器按照一定的顺序连接成一条链,称为拦截器链(Interceptor Chain),拦截器也是AOP思想的具体实现。
1.自定义拦截器:
- 创建拦截器类实现HandlerInterceptor接口
- 在spring-mvc.xml中配置拦截器
- 拦截效果测试
package com.itcast.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor1 implements HandlerInterceptor {
//1.在目标方法执行之前执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandler......");
String param = request.getParameter("param");
if ("param".equals("yes")) {
return true;
} else {
request.getRequestDispatcher("/jsp/error.jsp").forward(request, response);
return false;
}
}
//2.在目标方法执行只有、视图对象返回之前执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle......");
}
//3.在整个流程都执行完毕之后 执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion......");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.配置spring-->
<!--全局化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--2.配置springmvc-->
<!--springmvc前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1.mvc注解驱动-->
<mvc:annotation-driven/>
<!--2.配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3.静态资源访问权限开放-->
<mvc:default-servlet-handler/>
<!--4.注解扫描 扫描controller-->
<context:component-scan base-package="com.itcast.controller"/>
<!--配置spring拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--对那些资源进行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.itcast.interceptor.MyInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
2.拦截器实现登录
(1)用户在没有登录的情况下:
用户在没有登录的情况下不能对后台菜单进行访问操作,如果访问任何页面则将强制跳转到登录页面。
package com.itcast.interceptor;
import com.itcast.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class PrivilegeInterceptor implements HandlerInterceptor {
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;//放行访问目标资源
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1.mvc注解驱动-->
<mvc:annotation-driven/>
<!--2.配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3.静态资源访问权限开放-->
<mvc:default-servlet-handler/>
<!--4.注解扫描 扫描controller-->
<context:component-scan base-package="com.itcast.controller"/>
<!--配置权限拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--配置对哪些资源进行拦截操作-->
<mvc:mapping path="/**"/>
<!--配置哪些资源排除拦截操作-->
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.itcast.interceptor.PrivilegeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
(2)用户登录进行登录操作:
只有用户登录成功后才能对后台功能进行操作:
<div class="login-box-body">
<p class="login-box-msg">登录系统</p>
<form action="${pageContext.request.contextPath}/user/login" method="post">
<div class="form-group has-feedback">
<input type="text" name="username" class="form-control" placeholder="用户名"> <span
class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control" placeholder="密码"> <span
class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label><input type="checkbox"> 记住 下次自动登录</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">登录</button>
</div>
<!-- /.col -->
</div>
</form>
<a href="#">忘记密码</a><br>
</div>
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
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";
}
}
public class UserServiceImpl implements UserService {
//userDao依赖注入
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public User login(String username, String password) {
User user = userDao.findByUsernameAndPassword(username, password);
return user;
}
}
public class UserDaoImpl implements UserDao {
//注入jdbc模板
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User findByUsernameAndPassword(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;
}
}
二、SpringMVC异常处理
1.异常处理的思路:
系统中异常包括两类:预期异常和运行时异常RuntimeException,
前者通过捕获异常从而获取异常信息,后者通过规范代码开发、测试等手段减少运行时异常的发生。
系统的Dao、Service、Controller层出现都通过throwsException向上抛出异常,最后通过SpringMVC前端控制器交给异常处理器处理:
2.异常处理的方式:
(1)SimpleMappingExceptionResolver
使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver进行异常处理,
SpringMVC已经定义了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置:
(2)HandlerExceptionResolver接口实现
实现Spring的异常处理接口HandlerExceptionResolver自定义自己的异常处理器,
- 创建异常处理器类实现HandlerExceptionResolver
- 配置异常处理器
- 编写异常页面
- 测试
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof MyException) {
modelAndView.addObject("infor", "自定义异常");
} else if (e instanceof ClassCastException) {
modelAndView.addObject("infor", "类型转换异常");
}
modelAndView.setViewName("error");
return modelAndView;
}
}
<bean class="com.itcast.resolver.MyExceptionResolver"/>