拦截器和自定义注解@interface
1 .拦截器(Interceptor):
用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略。 拦截用户的请求并进行相应的处理,比如:判断用户是否登陆,判断用户权限,是否在可购买时间内,记录日志信息等。。
创建拦截器:实现HandlerInterceptor
@Component public class TestInterceptor implements HandlerInterceptor { //请求在进入Handler之前,该方法会被调用 //如果返回true,则表示该请求会继续往下执行,也就是才会执行到Handler //如果返回false,就不会执行到Handler,并且另外两个方法也不会执行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //因为我们使用的是注解形式的处理器(RequestMapping) //所以handler对象的真正的类型是HandlerMethod HandlerMethod hm = (HandlerMethod) handler; //获取该方法的注解对象 // hm.getMethodAnnotation(); HttpSession session = request.getSession(); Object user = session.getAttribute("user"); if (user != null){ return true; //放行 } response.sendRedirect("/log"); //重定向 return false; } /* Handler中的方法执行完毕之后,向客户端返回视图之前执行. 方法参数中的ModelAndView对象就是给客户端渲染所用的对象. */ @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 { } }
创建好一个拦截器,需要在spring配置文件中配置拦截器属性:
<mvc:interceptors> <mvc:interceptor>
<!--/**表示所有请求地址都要经过拦截器--> <mvc:mapping path="/**"/>
<!--下面表示这些地址可以不走拦截器--> <mvc:exclude-mapping path="/log"/> <mvc:exclude-mapping path="/login"/> <mvc:exclude-mapping path="/relog"/> <mvc:exclude-mapping path="/home"/>
<!--在拦截器类上加了注解@Component,所以可以直接引入拦截器id,表明上面被拦截的地址需要经过哪个拦截器--> <ref bean="testInterceptor"/> </mvc:interceptor> </mvc:interceptors>
自定义注解,配合拦截器完成一些功能:
2. 自定义注解:
新建一个类,将class属性改为@interface ,这个类就变成一个自定义注解了
/* 注解上面需要配置这个注解可以用到哪里: 例如:是给类用的,还是给属性用的,还是给方法用的 */ @Target(ElementType.METHOD) //这个注解是在运行时候生效的 @Retention(RetentionPolicy.RUNTIME) public @interface CheckPermission { String value(); }
在需要获取请求参数的处理器头部添加该自定义注解,
@Controller public class UserController { @CheckPermission("one") @RequestMapping("/one") public String one(){ return "one"; } @CheckPermission("two") @RequestMapping("/two") public String two(){ return "two"; } @CheckPermission("three") @RequestMapping("/three") public String three(){ return "three"; } @CheckPermission("four") @RequestMapping("/four") public String four(){ return "four"; } }
通过获取这个注解的参数,配合拦截器可以做一个权限的功能;
package com.lanou.demo.interceptor; import com.lanou.demo.annotation.CheckPermission; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; 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; import java.util.List; @Component public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); List<String> list = (List<String>) session.getAttribute("arr"); //获取Handler信息 HandlerMethod mv = (HandlerMethod) handler; //判断这个请求方法是否有这个注解 if (mv.hasMethodAnnotation(CheckPermission.class)) { //通过这个注解获取到请求地址 CheckPermission annotation = mv.getMethodAnnotation(CheckPermission.class); String value = annotation.value(); if (list != null){ //判断这个地址是否有权限 if (list.contains(value)) { //有权限,放行 return true; } } } //没有权限,重定向到某个页面 response.sendRedirect("/log"); 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 { } }