springMVC - 拦截器与全注解开发

拦截器

拦截器(Interceptor)类似于过滤器(Filter)

SpringMVC的拦截器作用是在请求到达控制器之前或之后进行拦截。可以对请求和响应进行一些特定的处理。

拦截器的应用场景如下:

  1. 登录验证:使用拦截器可以判断用户是否已经登录,如果未登录则跳转到登录页面。
  2. 权限校验:根据用户权限进行访问控制,拒绝未经授权的用户访问
  3. 请求日志:记录请求信息,如请求地址、请求参数、请求时间,用于排查问题和性能优化
  4. 更改响应:可以对响应内容进行修改,例如添加头信息、调整响应内容格式等。

拦截器和过滤器的区别在于他们作用层面不同:

  • 过滤器注重在请求和响应的流程种进行处理。可以修改请求和响应的内容。例如设置编码和字符集、请求头、状态码等。
  • 拦截器侧重对控制器进行前置或后置处理,在请求到达控制器之前或之后进行特定操作,例如打印日志、权限验证等

无标2

定义拦截器与配置

实现HandlerInterceptor接口,共有三个方法可以进行选择性实现:

  • preHandle :处理器方法调用之前执行

只有该方法有返回值,返回值是布尔类型。true方向,false拦截

  • postHandle:处理器方法调用之后执行
  • afterCompletion:渲染完成后执行

自定义的拦截器类:

public class Interceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

在springmvc.xml文件中配置如下:

<!--    配置拦截器-->
    <mvc:interceptors>
<!--       基本配置: 第一种方式,默认拦截所有请求-->
        <bean class="com.ali.interpectors.Interceptor1"/>
       <!-- 基本配置: 第二种方式,将Interceptor1这个拦截器类加上@Compentent注解,交给Spring容器管理,然后在这里通过ref标签引用它-->
        <ref bean="interceptor1"/>
    </mvc:interceptors>

拦截器的高级配置

以上基本配置方式,拦截器拦截所有请求。如果要针对某些路径进行拦截,某些路径不拦截,可以采用高级配置:

<!--    配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
<!--            拦截所有请求-->
            <mvc:mapping path="/**"/>
<!--            除//test/路径以外的所有请求都会被该拦截器拦截-->
            <mvc:exclude-mapping path="/test/"/>
<!--            拦截器-->
            <ref bean="interceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器的执行顺序

  1. 如果所有拦截器preHandle 都返回true。按照配置文件中配置顺序自上而下调用preHandle
    <mvc:interceptors>
    <!--            拦截器-->
          <ref bean="interceptor1"/>
          <ref bean="interceptor2"/>
          <ref bean="interceptor3"/>
    </mvc:interceptors>

无标3题

  1. 如果某个拦截器的preHandle 返回false,那么处理器方法和所有拦截器的postHandle方法都不会执行,而且自己的afterCompletion也不会执行,但是其他拦截器的afterCompletion会执行。

    比如interceptor3的preHandle 返回false

无4标3题

springMVC执行流程

无5标题

全注解开发

Servlet3.0新特性

web.xml替代

Servlet3.0新特性:web.xml可以不写了。

Servlet3.0提供了ServletContainerInitializer接口,服务器在启动的时候会自动从容器中找ServletContainerInitializer接口的实现类,自动调用它的onStartup方法来完成Servlet上下文初始化。

无6标题

1.编写WebAppInitializer类替代web.xml文件

// 替代web.xml文件
@Configuration
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    // 配置spring的配置文件
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    // 配置springmvc的配置文件
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    // 配置DispatcherServlet的映射信息
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    // 配置过滤器
    @Override
    protected Filter[] getServletFilters() {
        // 配置字符编码过滤器
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceRequestEncoding(true);
        characterEncodingFilter.setForceResponseEncoding(true);
        // 配置hiddenHttpMethodFilter过滤器
         HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
    }
}

springmvc.xml替代

// 替换springmvc的配置文件
@Configuration
// 组件扫描
@ComponentScan("com.ali.controller")
// 启用SpringMVC,开启注解驱动,相当于在xml中配置了<mvc:annotation-driven/>
@EnableWebMvc
public class SpringMVCConfig implements WebMvcConfigurer {
    // 配置视图解析器=======================================
    @Bean
    public ThymeleafViewResolver getViewResolver(SpringTemplateEngine springTemplateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(springTemplateEngine);
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setOrder(1);
        return viewResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    @Bean
    public ITemplateResolver templateResolver(ApplicationContext applicationContext) {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setCacheable(false); // 开发阶段不启用缓存,生产环境可以启用
        return templateResolver;
    }
    // ====================================================

    // 开启静态资源的处理,开启默认的servlet处理器,等同于在xml中配置了<mvc:default-servlet-handler/>
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    // 开启视图控制器的映射,等同于在xml中配置了<mvc:view-controller path="/" view-name="index"/>
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }

    // 配置异常处理器,等同于在xml中配置了<mvc:annotation-driven>中的<exception-resolver>
    // 这里我们使用了SpringMVC提供的SimpleMappingExceptionResolver来处理异常
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        // 可以配置多个异常处理器,这里我们只配置了一个SimpleMappingExceptionResolver
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        // 配置异常映射,key是异常类的全路径,value是视图名称
        properties.setProperty("java.lang.Exception", "error");
        properties.setProperty("java.lang.RuntimeException", "error");
        exceptionResolver.setExceptionMappings(properties);
        exceptionResolver.setDefaultErrorView("error"); // 默认的错误视图
        exceptionResolver.setExceptionAttribute("ex"); // 在视图中可以通过${ex}来获取异常对象
        resolvers.add(exceptionResolver);
    }

    // 配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 配置拦截器,拦截所有请求,除了/test路径
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/test");
    }
}
posted @ 2026-02-28 19:20  NE_STOP  阅读(13)  评论(0)    收藏  举报