03:SpringBoot自定义MVC配置---拦截器,转换器,静态资源等

03:SpringBoot自定义MVC配置---拦截器,转换器,静态资源等

Scroll Down

在web应用中,我们总是会涉及许多静态资源,如css、js以及图片等文件需要进行映射访问,否者在mvc中会无法访问。而且在spring中定义了许多转换器供我们使用,但是有时候在自己的业务逻辑中的数据模型中需要进行特定的转换,以及拦截某些请求进行权限控制,所以就需要我们定义、部署特定的拦截器以及转换器。在spring mvc中,我们都是实现对应的接口或者扩展某个类,然后在XML文件中部署即可,如下所示:

<!--拦截器-->
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.test.service.interceptor.UserPermissionInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
<!--静态资源映射-->
   <mvc:resources mapping="/photo/**" location="/image/waifphoto/"/>



    <mvc:resources mapping="/img2/**" location="image/webPhoto/"/>

而在springboot中,配置基本都是基于java的,所以今天来说说springboot中的配置方式。

WebMvcConfigurer接口:

在spring boot官方文档中给出的spring boot自定义mvc的拦截器等是通过扩展WebMvcConfigurerAdapter类配合@Configuration注解和可能存在的@EnableWebMvc注解重写某些方法实现。但是在我使用的时候发现该类已经被@Deprecated(过时了),查了下资料,现在一般使用WebMvcConfigurer接口或者WebMvcConfigurationSupport类,我使用的是前者,我们查看一下该接口,定义如下:

public interface WebMvcConfigurer {
    default void addFormatters(FormatterRegistry registry) {
    }
    default void addInterceptors(InterceptorRegistry registry) {
    }
    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }
    default void addCorsMappings(CorsRegistry registry) {
    }
    default void addViewControllers(ViewControllerRegistry registry) {
    }
    default void configureViewResolvers(ViewResolverRegistry registry) {
    }
    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }
    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
    }
    //此处省略若干方法.....
}

在接口中我们可以看到addResourceHandlers、addInterceptors、addFormatters等若干方法,分别是添加静态资源处理器、添加拦截器以及添加格式化器等等,具体请详见源码或者api文档。此处重点也就是上面三个方法,我们将使用它们配置静态资源、拦截器等。

spring boot实现拦截器、静态资源等配置:

  • 配置静态资源:

  1. 基于java的配置:
@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/mystatic/**")
                .addResourceLocations("/static/");
    }

在上面我们重写了接口中的方法,我们就可以通过“/mystatic/”访问“/static/”下的资源了。等效如下的XML配置:

 <mvc:resources mapping="/mystatic/**" location="/static/"/>

2.基于配置文件的方式:
只需要在application.yaml中增加如下配置即可:

spring:
  mvc:
    static-path-pattern: /mystatic/**
    resources:
      static-locations: classpath:/static/
  • 配置拦截器:

先定义自己的拦截器,实现HandlerInterceptor接口。该接口中提供以下三个方法

        //处理器处理前执行,返回true才进一步处理,否则不予以处理
        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 {
    }

在其中选择需要的方法进行重写,此时我实现的拦截器如下:

public class LoginInterceptor implements HandlerInterceptor
{
    private Log log= LogFactory.getLog(LoginInterceptor.class);
    /**
     * 访问拦截器
     * 根据是否具有user属性判断
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception
    {
        String url=request.getRequestURI();
        System.out.println("url:"+url);
        if (url.contains("Login")||url.contains("register"))
        {
            log.info("登陆及注册,通行.....");
            return true;
        }
        log.info("非登陆注册请求....");
        if (request.getSession().getAttribute("user")==null)
        {
            response.sendRedirect("/springboot/user/Login");
            return false;
        }
        log.info("已登陆用户....");
        return true;
    }
}

部署拦截器:

 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")    //需要拦截的url
                .excludePathPatterns("/url_exclude");  //不需要拦截的url
    }
  • 配置转换器:

  1. 通过实现接口注册转换器:
    先通过实现Converter接口,定义自己的转换器,如下:
@Component
public class DataFormater implements Converter<String,Integer>
{
    @Override
    public Integer convert(String integer)
    {
        //使用url参数age=10#20测试
        Integer integer1=Integer.valueOf(integer.split("#")[0]);
        return integer1;
    }
}

部署:

@Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(dataFormater);
    }
  1. 也可以通过@Configuration和@Bean直接注册转换器组件,但是会覆盖掉默认的转换器配置。

总结:

  • 实现WebMvcConfigurer接口。
  • 在实现WebMvcConfigurer接口的类上使用@Configuration,标注为配置类。
  • 轻易不要使用@EnableWebMvc注解,该注解会覆盖spring boot提供的默认mvc配置,需要完全接管spring mvc,那么就可以放心使用@EnableWebMvc注解了。
  • 结合api文档,重写需要的方法即可。

小弟才疏学浅,如有错误,欢迎大佬指正,非常感谢!