spring boot--拦截器实现

spring boot给我们提供了一个HandlerInteceptor接口帮助我们实现拦截器功能。

在HandlerInteceptor接口中,一共有三个default方法(这是jdk8的新特性,用来在接口中编写带有方法体的方法。实现接口可以不重写default方法,那么默认调用的仍是接口中的default方法体)

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
boolean preHandle:会在controller处理前调用该方法,方法返回true则进入对应的controller。方法返回false则不会进入controller。可以用来编码,安全控制,权限校验等。
void postHandle:在controller处理完成返回ModelAndView后执行。此时还没有进行视图渲染,还可以修改ModelAndView。
void afterCompletion:整个请求已经处理完成了,可能返回了正常的请求结果,也可能返回一个异常。

下面我们来做一个简单的demo。

先定义一个controller:

@RestController
public class UserController {

    @GetMapping("users/{id}")
    public String getUser(@PathVariable("id") String id) {
        System.out.println("controller[url=users/" + id + "]");
        return "testUser";
    }

    @GetMapping("users/login")
    public String test(User user, Model model) {
        System.out.println("controller[url=users/login]");
        model.addAttribute("id", user.getId());
        model.addAttribute("name", user.getName());
        model.addAttribute("password", user.getPassword());
        model.addAttribute("mail", user.getMail());
        return "index";
    }
}

里面提供了两个请求链接:/users/{id}和/users/login,这里为了简单方便,我们均设置请求方式为get。

定义一个拦截器UserInteceptor(这里先测试第一个方法preHandle):

@Component
public class UserInteceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle;");
        Map<String, String[]> map = request.getParameterMap();
        map.forEach((k, v) -> {
            System.out.println("[Key=" + k + ";Value=" + StringUtils.join(v) + "];");
        });
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

然后将拦截器添加进容器中,设定它的拦截路径为/users/**:

@Configuration
public class InteceptorConfig implements WebMvcConfigurer {

    @Autowired
    private UserInteceptor userInteceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userInteceptor).addPathPatterns("/users/*");
    }
}

就此一个简单的项目已经构成,我们启动程序,然后访问/users/login?id=1&username=yxf&password=123&[email protected]

可以看到访问结果:

preHandle; //----------------------------调用了preHandle方法
[Key=id;Value=1]; //---------------------打印request中的id
[Key=name;Value=yxf]; //-----------------打印request中的name
[Key=password;Value=123]; //-------------打印request中的password
[Key=mail;Value=5@qq.com]; //------------打印request中的mail
controller[url=users/login] //-----------在preHandle之后,这里进入UserController的test方法。
postHandle //----------------------------controller处理完成后调用PostHandle方法。
//------------------------------在这中间其实还有dispatchServlet调用视图解析器对View的解析等---------------------------- afterCompletion //-----------------------postHandle处理完成后调用afterCompletion。

猜你喜欢

转载自www.cnblogs.com/yxth/p/10865396.html