Detailed DispatcherServlet arranged in a plurality of spring boot

We spring boot is automatically configured with the DispatcherServlet a box, map the path of '/', but if there are a plurality of service items, for different configurations for different management services necessary to provide a different context for different services, for example, open a DispatcherServlet service dedicated to rest.

Traditional springMVC project

In traditional springMVC project, DispatcherServlet easily configure multiple, multiple configuration in web.xml directly on the line:

<servlet>
  <servlet-name>restServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring2.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>ModelRestServlet</servlet-name>
  <url-pattern>/service/*</url-pattern>
</servlet-mapping>

It can be specified by specifying the context for this DispatcherServlet init-param of contextConfigLocation.

spring boot is registered in two ways Servlet

But spring boot gave the tomcat hide, let alone the web.xml. Fortunately, it provides another way to configure the servlet.

1. @ WebServlet notes:

This is javaee notes, after servlet3.0 is provided. spring boot scans the annotation, and the annotation to the annotation class is registered as a web container servlet.

But not DispatcherServlet custom servlet, but servlet framework, so this method does not work.

2.ServletRegistrationBean:

This bean is provided by a special spring boot to register the servlet can be registered as the bean to configure the same servlet.

@Bean
public ServletRegistrationBean restServlet(){
  //注解扫描上下文
  AnnotationConfigWebApplicationContext applicationContext
      = new AnnotationConfigWebApplicationContext();
  //base package
  applicationContext.scan("com.jerryl.rest");
  //通过构造函数指定dispatcherServlet的上下文
  DispatcherServlet rest_dispatcherServlet
      = new DispatcherServlet(applicationContext);
 
  //用ServletRegistrationBean包装servlet
  ServletRegistrationBean registrationBean
      = new ServletRegistrationBean(rest_dispatcherServlet);
  registrationBean.setLoadOnStartup(1);
  //指定urlmapping
  registrationBean.addUrlMappings("/rest/*");
  //指定name,如果不指定默认为dispatcherServlet
  registrationBean.setName("rest");
  return registrationBean;
}

Which should be noted is registration.setName ( "rest"), the statement is important because the same name ServletRegistrationBean only one take effect, that is to say, after the registration will overwrite the same name ServletRegistrationBean.

If not specified, the default is "dispatcherServlet" and spring boot provided DispatcherServlet the name is "dispatcherServlet". Can be found in DispatcherServletAutoConfiguration class spring boot of:

 public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
    ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, new String[]{this.serverProperties.getServletMapping()});
    registration.setName("dispatcherServlet");
    registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
    if(this.multipartConfig != null) {
      registration.setMultipartConfig(this.multipartConfig);
    }
 
    return registration;
  }
}

Therefore, in order not to override the default dispatcherServlet, you must specify a different name.

Meanwhile, in the DispathcerServlet bound custom configuration class, to configure the scan report, then, it must be added @EnableWebMvc comment, or will not scan @Contrller comment.

package com.jerryl.rest;

@Configuration
@ComponentScan("org.activiti.rest.service.api")
@EnableWebMvc
public class Cfg_Rest {
···
}

Shielding rest DispatcherServlet service access to static resources

Finally, there is a small problem, because you want additional configuration of a DispatcherServlet rest dedicated to providing services, but after this configuration, when accessing localhost / rest / accesses to pages and other static resources, it feels strange.
Since spring boot default static mapping of resources to do, but if you do not want to access any static resources, you can modify the map.

In two ways:

1. In the configuration application.yml:

spring:

mvc:
 #默认为/**
 static-path-pattern: /**
resources:
 #默认为classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 。配置多个路径,中间用逗号隔开。
 static-locations:

If configured here, it will affect the entire springboot project. But the default is DispatcherServlet need access to static resources can not be configured here.

2. A successor WebMvcConfigurerAdapter of java class configuration:

@Configuration
@EnableWebMvc
public class Cfg_View extends WebMvcConfigurerAdapter{
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**");
  }
}

Rewrite addResourceHandlers method, specifying only resourceHandler, do not specify resourceLocation, so it can intercept write off all access to static resources, and does not return any static resources. Here is the configuration can be specified, just let DispatcherServlet responsible for scanning the context of the rest of the service class configuration on it. It does not affect the default DispatcherServlet.

Guess you like

Origin blog.csdn.net/qq_37272886/article/details/95318440