SSM8=SpingMVC过滤器addResourceHandlers和拦截器HandlerIntercetor=过滤器javax.servlet.Filter和DispatchServlet和AOP

回到最开始我们使用tomcat搭配web.xml。

Tomcat启动时加载配置有着先后顺序。
web.xml的加载顺序是:<context-param> -> <listener> -> <filter> -> <servlet>。

context-param设置应用的ServletContext上下文初始化参数,所以最先加载。

=========================================================

上面是传统的用web.xml来配置,但是我们现在已经使用实现WebMvcConfigurer的配置类SpringMvcConfig来替代web.xml。对比之下,可以看到:

对应的监听器listener通过WebAppRootListener 替代。

对应的过滤器filter通过在SpringMvcConfig重写addResourceHandlers替代。

对应的servlet通过DispatcherServlet分发搭配@Controller@RequestMapping等替代。

======================================================================

拦截器呢?Javaweb中好像没这个说法,springMVC才设计拦截器的概念,首次执行是在DispatcherServlet分发之后controller执行之前。只用Javaweb的话使用过滤器Filter或者代理能够实现相似的功能。

拦截器的常用场景:springmvc框架帮我们简化操作后的东西,能用拦截器就用拦截器,别用javax.servlet.Filter和自己写代理和AOP

        (1 )解决乱码问题:乱码在项目中经常 遇到,或许是因为代码编辑工具的问题,也可
能是字符编码问题,但有拦截器后,都可在请求发出之前统一设置编码。
        (2)解决权限认证问题:很多项目如商 城项目,必须用户登录后才能去购买商品,那
么此时在请求发出前,需要判断用户是否已经 登录,此时在拦截器中就可先判断用户是否登
录,若未登录,就跳转到登录界面等。
拦截器与过滤器的对比与总结
        首先,拦截器和 过滤器的依赖是不同的,如果你使用的项目没 有使用到 Spring MVC 框架,那么此时你就是 不能使用拦截器,因为拦截器依赖框架容器, 其本身基于 java 中的反射机制,而过滤器即 使没有 Spring MVC 框架支持,也可以使用, 因为过滤器是基于 Servlet 容器的,并通过了 回调函数来使用。那么到此为止,对于拦截器 的描述就结束了,拦截器可以处理我们在 Web
项目中请求的通用性的问题,合理使用拦截器, 可以减少我们的代码工作量,同时项目也便于维护。

 =========================================================================

过滤器示例:

springMVC的过滤器addResourceHandlers。指向静态资源的路径。

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    //    过滤器
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    //拦截器
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //配置拦截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    }
}

拦截器示例:

springMVC的拦截器是实现 HandlerInterceptor或者WebRequestInterceptor,根据请求路径,对交给MVC对应的IOC容器管理的controller中的方法做增强,在方法执行前后加些操作。


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;

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        System.out.println("preHandle..."+contentType);
        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...");
    }
}
//拦截器
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //配置拦截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    }

有了拦截器还有必要写AOP吗?有。

        因为按照我们之前的配置,只将controller交给了MVC对应的IOC容器管理,拦截器只能增强MVC对应的IOC容器中的controller中的方法,不能对service层dao层的接口实现类中的方法进行增强。而自己手写的@Pointcut("execution(* com.ldj.service.*Service.*(..))")和@Around("servicePt()")

AOP却可以对普通spring IOC容器和MVC IOC容器管理的bean中的方法都进行增强。

        可以说拦截器是MVC帮我们包装过后的AOP操作,我们也可以自己根据AOP自己写拦截器,但spring MVC帮我们写好了一个HandlerInterceptor 接口直接拿来用方便多了。

========================================================================

官方文档拦截器示例:通过注解或者XML两种方式

You can configure HandlerInterceptors or WebRequestInterceptors to be applied to all

incoming requests or restricted to specific URL path patterns.

An example of registering interceptors in Java:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
 registry.addInterceptor(new LocaleInterceptor());
 registry.addInterceptor(new ThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/
admin/**");
 registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
 }
}

And in XML use the <mvc:interceptors> element:

<mvc:interceptors>
 <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
 <mvc:interceptor>
 <mvc:mapping path="/**"/>
 <mvc:exclude-mapping path="/admin/**"/>
 <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
 </mvc:interceptor>
 <mvc:interceptor>
 <mvc:mapping path="/secure/*"/>
 <bean class="org.example.SecurityInterceptor"/>
 </mvc:interceptor>
</mvc:interceptors>

 老版本spring官方文档对拦截器的说明:

                13.4.3。拦截请求——HandlerInterceptor接口
        Spring的处理程序映射机制具有处理程序拦截器的概念,当您想要将特定的功能应用到特定的请求(例如,检查主体)时,它会非常有用。
        位于处理程序映射中的拦截器必须从org.springframework.web.servlet包中实HandlerInterceptor。该接口定义了三个方法,一个方法将在实际处理程序执行之前调用,一个方法将在处理程序执行之后调用,另一个方法将在完整请求完成后调用。这三种方法应该提供足够的灵活性来进行各种预处理和后处理。
        三种方法返回一个布尔值。您可以使用此方法中断或继续执行链的处理。该方法返回true时,处理程序链将继续执行,当它返回false, DispatcherServlet假定请求拦截器本身照顾(例如,呈现一个适当的视图),不继续执行其他拦截器和实际处理程序在执行链。下面的示例提供了一个拦截器,如果时间不在上午9点到下午6点之间,拦截所有请求并将用户路由到特定页面。

        如上示例任何传入的请求都将被TimeBasedAccessInterceptor拦截,如果当前时间不在办公时间,用户将被重定向到一个静态html文件,例如,他只能在办公时间访问该网站。

        如您所见,Spring有一个适配器类(巧妙地命名为HandlerInterceptorAdapter),以便更容易扩展HandlerInterceptor接口。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值