18、springboot——嵌入式servlet容器修改+注册servlet三大组件
SpringBoot默认使用Tomcat作为嵌入式的Servlet容器
1)、如何定制和修改Servlet容器的相关配置
1、修改和server有关的配置
(ServerProperties【也是EmbeddedServletContainerCustomizer】)
server.port=8088
server.servlet.context-path=/crud
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx
server.tomcat.uri-encoding=UTF-8
2、编写一个EmbeddedServletContainerCustomizer:
嵌入式的Servlet容器的定制器;来修改Servlet容器的配置
在Spring Boot2.0以上配置嵌入式Servlet容器时
EmbeddedServletContainerCustomizer类不存在,
经网络查询发现被WebServerFactoryCustomizer替代
@Configuration public class MyServerConfig { //配置嵌入式的Servlet容器 @Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer(){ return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() { //定制嵌入式的Servlet容器相关的规则 @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(8083); } }; } }
2)、注册Servlet、Filter、Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动
SpringBoot的web应用,没有web.xml文件
使用一下三个类:
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
1、注册Servlet
Servlet实现类:
public class MyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("hello"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } }
ServletRegistrationBean实现Servl加入容器
@Configuration public class MyServerConfig { //注册三大组件 //1、注册Servlet @Bean public ServletRegistrationBean myServlet(){ ServletRegistrationBean<MyServlet> registrationBean = new ServletRegistrationBean<>(); registrationBean.setServlet(new MyServlet()); registrationBean.addUrlMappings("/myServlet"); return registrationBean; } //配置嵌入式的Servlet容器 @Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer(){ return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() { //定制嵌入式的Servlet容器相关的规则 @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(8083); } }; } }
2、注册Filter
编写自定义的filter
public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("MyFilter..."); filterChain.doFilter(servletRequest,servletResponse); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
加入容器
@Configuration public class MyServerConfig { //注册三大组件 //1、注册Servlet @Bean public ServletRegistrationBean myServlet(){ ServletRegistrationBean<MyServlet> registrationBean = new ServletRegistrationBean<>(); registrationBean.setServlet(new MyServlet()); registrationBean.addUrlMappings("/myServlet"); return registrationBean; } //2、注册Filter @Bean public FilterRegistrationBean myFilter(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new MyFilter()); registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet")); return registrationBean; } //配置嵌入式的Servlet容器 @Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer(){ return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() { //定制嵌入式的Servlet容器相关的规则 @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(8083); } }; } }
再访问/myServlet的时候经过过滤器后控制台打印响应字符串
3、注册Listener:
编写自定义Listener
public class MyListener implements ServletContextListener { //监听当前web项目销毁 @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("web end...."); } //启动监听 @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("web start..."); } }
加入容器
@Configuration public class MyServerConfig { //注册三大组件 //1、注册Servlet @Bean public ServletRegistrationBean myServlet(){ ServletRegistrationBean<MyServlet> registrationBean = new ServletRegistrationBean<>(); registrationBean.setServlet(new MyServlet()); registrationBean.addUrlMappings("/myServlet"); return registrationBean; } //2、注册Filter @Bean public FilterRegistrationBean myFilter(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new MyFilter()); registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet")); return registrationBean; } //3、注册Listener @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean(){ ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean(); registrationBean.setListener(new MyListener()); return registrationBean; } //配置嵌入式的Servlet容器 @Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer(){ return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() { //定制嵌入式的Servlet容器相关的规则 @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(8083); } }; } }
同时可以设置的参数很多如load-starton......
SpringBoot帮我们自动SpringMVC的时候,自动的注册SpringMVC的前端控制器;
DIspatcherServlet;DispatcherServletAutoConfiguration中:
@Bean( name = {"dispatcherServletRegistration"} ) @ConditionalOnBean( value = {DispatcherServlet.class}, name = {"dispatcherServlet"} ) public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) { DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, this.webMvcProperties.getServlet().getPath()); //默认拦截: / 所有请求;包静态资源,但是不拦截jsp请求 // /*会拦截jsp //可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径 registration.setName("dispatcherServlet"); registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup()); if (this.multipartConfig != null) { registration.setMultipartConfig(this.multipartConfig); } return registration; }
getPath->WebMvcProperties -> private String path = "/";