spring boot 2.0 设置多个DispatcherServlet

最近在学习spring boot,刚好遇到一个需求比较简单的项目,就拿新搭好的框架(springboot + druid + mybatis + mybatis-generator)来练手,因为有前端接口和后台管理两个部分,按照以前使用springmvc的习惯,我想设置多个dispatcherservlet实现前端接口和后台管理端路径规则的分离,并分别添加拦截器,在这个过程中遇到了一些问题,折腾好久后终于解决,特此记录。

1、配置多个DispatcherServlet:spring boot 提供了ServletRegistrationBean这个bean专门来注册servlet,可以像注册bean一样注册servlet,具体的在启动类Application中注册即可,如下:

@Bean
    public ServletRegistrationBean backServlet() {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.scan("com.wc.h5case.controller.back");
        applicationContext.register(BackServletConfig.class);
        dispatcherServlet.setApplicationContext(applicationContext);
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/manager/admin/*");
        servletRegistrationBean.setLoadOnStartup(1);
        // 这一句很关键,因为name相同的只有一个会生效,后面注册的会覆盖前面的
        servletRegistrationBean.setName("back");
        return servletRegistrationBean;
    }

2、添加拦截器,为后台管理添加登录拦截器,中间遇到个小插曲,就是自定义了配置文件,在注入拦截器的时候报错空指针,查了资料发现需要将自定义的拦截器注册到spring bean中,启动时拦截器才能取到配置的值。

/**
 * 将自定义拦截器注册到spring bean中
 * 解决拦截器中Bean无法注入的问题(配置信息无法注入AdminProperties)
 */
@Bean
public AdminLoginInterceptor adminLoginInterceptor() {
    return new AdminLoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
    // 拦截器按照顺序执行
    registry.addInterceptor(adminLoginInterceptor()).addPathPatterns("/manager/admin/*");
}

3、以上两步完成在测试的时候发现一件很神奇的事情,controller.back包中增加了个测试类,我以为只有/manager/admin/test/index.do才能访问,结果发现直接/test/index.do也可以,这就不好玩了,达不到效果,这时候可以把默认的DispatcherServlet禁用掉

// exclude 把默认的匹配规则/去掉
@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class)

4、这一设置,上面的目的是达到了,但又出现个新问题,静态资源访问不到了,于是按照网上的做法开始折腾,重写了addResourceHandlers方法,如下:

/**
 * 配置类,自定义拦截器
 */
@Configuration
public class RunWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }
}

结果直接访问/css/index.css还是访问不到,/manager/admin/css/index.css倒是可以,这还是有点逼死强迫症的,如鲠在喉,后面想想是不是再加个专门访问静态资源的DispatcherServlet就可以解决问题了,于是乎试了一波:

@Bean
public ServletRegistrationBean resourceServlet() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.setApplicationContext(applicationContext);
    ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet);
    servletRegistrationBean.addUrlMappings("*.css", "*.js", "*.ttf", "*.png", "*.jpg", "*.gif", "*.woff", "*.woff2");
    servletRegistrationBean.setLoadOnStartup(1);
    servletRegistrationBean.setName("resource");
    return servletRegistrationBean;
}

到这里,确实可以实现我最初的设想和需求,但总觉得有些麻烦,哪位大佬若有其他解决方式,欢迎留言探讨。

参考文章:
https://stackoverflow.com/questions/30670327/spring-boot-with-multiple-dispatcherservlet-each-having-their-own-controllers

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值