Java 过滤器实现(登录) + 拦截器(两种方法)

以下是实现未登录不能进入页面的实现
使用了thyemeleaf+SpringBoot+过滤器实现的,过滤器的核心代码如下:
@Component
@WebFilter(filterName = "TestFilter",urlPatterns = "/*")
@Order(1)  //Order(1)在定义多个Filter时,用于决定执行顺序的,数字越小,越先执行。
public class TestFilter implements Filter {
    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList("/index", "/login")));
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        //这样在每个Servlet执行的时候都会先进行这个
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.println("过滤器实现");
        if(needLogin(request)) {
            // 需要登录则跳转到登录Controller
            String userName = (String)((HttpServletRequest) request).getSession().getAttribute("userName");
            System.out.println("userName="+userName);
            System.out.println(Optional.ofNullable(userName).map(String::length).orElse(0));
            if(Optional.ofNullable(userName).map(String::length).orElse(0) <= 0){
                response.sendRedirect("login");
//              response.sendRedirect(request.getContextPath()+"/login");
            }
            filterChain.doFilter(servletRequest, servletResponse);
           return;
        }else{
        }
        //因为有可能不止这一个过滤器,所以需要将所有的过滤器执行
        //注意 这一行代码一定要写到最后
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }

    private boolean needLogin(HttpServletRequest request) {
        //进行是否需要登录的判断操作
        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
        System.out.println(path);
        boolean allowedPath = ALLOWED_PATHS.contains(path);
        System.out.println(allowedPath);
        return !allowedPath;
    }
 }
View Code

代码链接:

链接:https://pan.baidu.com/s/1Kvh4JWCM3aIpiaqK67Rw3g 密码:pa57

过滤器虽然也能实现,但是用起来会有个问题,假如说是我请求http://localhost:8080/usercenter,时,我期望的过程是,在过滤器里发现未登录,直接就跳转进入login,但是,实际山遇到的情况是,会先进入我的usercenter方法,跑过这个方法之后再进过滤器,再走login,这就会出现情况,假如说是我的usercenter方法(由于未登录导致出现方法中出现null的情况)有问题,导致最后页面报500

,为了解决这个问题,采用了拦截器,正好就是自己想要的效果,未登录的时候不进入usercenter,直接进入login

一下是拦截器代码:

拦截器的:

@Configuration
public class LoginInterceptor implements HandlerInterceptor {
    @Override  // 在执行目标方法之前执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("------:进来拦截器了!--1");
        //获取session
        HttpSession session = request.getSession(true);
        //判断用户ID是否存在,不存在就跳转到登录界面
        if(session.getAttribute("phoneNum") == null){
            System.out.println("------:跳转到login页面!");
            response.sendRedirect(request.getContextPath()+"/login");
            return false;
        }else{
            session.setAttribute("phoneNum", session.getAttribute("phoneNum"));
            return true;
        }
    }

    @Override  // 执行目标方法之后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("------:进来拦截器了!--2");
    }

    @Override  // 在请求已经返回之后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("------:进来拦截器了!--3");
    }
}
View Code

配置文件的:WebConfig.java的代码:

@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public WebConfig(){
        super();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/static/");
        registry.addResourceHandler("/templates/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/templates/");
        super.addResourceHandlers(registry);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截规则:除了login,其他都拦截判断
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/index", "/login","register");
        super.addInterceptors(registry);
    }

}
View Code

这样就能完美的解决过滤器时遇到的问题

结束

代码链接:链接:https://pan.baidu.com/s/1QusjeJ2EVo4K55xN_saooQ 密码:nh85

原文地址:https://www.cnblogs.com/myyBlog/p/8819919.html