Spring Boot |配置和切换Servlet容器


在使用SpringBoot之前,需要将Web应用打成war包,在外部配置好Tomcat的环境(Tomcat就是Servlet的容器),将web应用放在Tomcat上,在外部启动Tomcat;使用了SpringBoot时,无需使用外部Tomcat环境,原因就在于SpringBoot自带了嵌入式的Tomcat。本文详细介绍如何配置嵌入式Servlet容器。

一、配置嵌入式Servlet容器

SpringBoot默认使用Tomcat作为嵌入式的Servlet容器,可以在IDEA的pom文件中showDependencies,查看依赖图:

在这里插入图片描述
由依赖图可以发现SpringBoot默认使用了嵌入式的Servlet容器。这就出现了一个问题,之前使用外置的Tomcat如果想定制或优化,可以在conf目录的server.xml文件中修改。使用了SpringBoot后,可以在application.properties文件中定制和修改与server相关的配置。实际上修改的是ServerProperties类的属性。

  • 通用的Servlet容器可以设置为server.xxx
  • Tomcat相关的可以设置为tomcat.xxx
配置 说明
server.port=8081 设置项目访问路径
server.servlet.context-path=/crud 修改访问映射
server.tomcat.uri‐encoding=UTF‐8 设置编码格式

除了在application.properties文件中修改配置,还可以像下面的代码这样编写一个嵌入式Servlet容器定制器 ,来修改Servlet容器的配置,两种方式虽然实现上不同,但底层都是相同的原理。

@Configuration
public class MyServerConfig {
    /**
     * 配置嵌入式Servlet容器
     */
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>(){
            //定制嵌入式Servlet容器相关的规则
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8083);
            }
        };
    }
}

二、注册Servlet三大组件

SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器,进而启动SpringBoot的web应用,所以没有web.xml文件。(标准的Web目录结构,三大组件配置在src/main/webapp/WEB-INF/web.xml)。

Servlet三大组件 注册方式 自己的组件需要做的工作
Servlet ServletRegistrationBean 继承HttpServlet
Filter FilterRegistrationBean 实现Filter
Listener ServletListenerRegistrationBean 实现ServletContextListener

2.1 使用ServletRegistrationBean注册Servlet

@Configuration
public class MyServerConfig {
    /**
     * 注册Servlet:使用ServletRegistrationBean
     */
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
        return registrationBean;
    }
}

创建自己的Servlet需要实现HttpServlet接口。

public class MyServlet extends HttpServlet {
    //处理GET请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    //处理POST请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("Hello MyServlet");
    }
}

2.2 使用FilterRegistrationBean注册Filter

@Configuration
public class MyServerConfig {
    /**
     * 注册Filter:使用FilterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new MyFilter());
        registrationBean.setUrlPatterns(Arrays.asList("/hello", "/myServlet"));
        return registrationBean;
    }
}

创建自己的Filter需要实现Filter接口。

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter process...");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

2.3 使用ServletListenerRegistrationBean注册Listener

@Configuration
public class MyServerConfig {
    /**
     * 注册Listener:使用ServletListenerRegistrationBean
     */
    @Bean
    public ServletListenerRegistrationBean myListener() {
        ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<MyListener>(new MyListener());
        return registrationBean;
    }
}

创建自己的Listener需要实现ServletContextListener接口。

public class MyListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized...web应用启动");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed...当前web项目销毁");
    }
}

三、切换为其他嵌入式Servlet容器

SpringBoot默认使用Tomcat,除此之外,SpringBoot还支持Jetty容器(适合长链接应用,)、Undertow容器(不支持JSP,但是性能高、非阻塞、并发性能好)

在这里插入图片描述

3.1 切换为Jetty容器

打开pom文件的依赖图,excloud掉spring-boot-starter-tomcat之后,引入Jetty容器。

        <!--引入Jetty容器-->
        <dependency>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加载完毕,就可以看到生成了Jetty的依赖。
在这里插入图片描述

3.2 切换为Undertow容器

打开pom文件的依赖图,excloud掉spring-boot-starter-tomcat之后,引入Undertow容器。

  		<!--引入Undertow容器-->
        <dependency>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加载完毕,就可以看到生成了Undertow的依赖。
在这里插入图片描述

四、切换为外部Servlet容器

使用嵌入式Servlet容器的优点在于简单、便捷、直接打成jar包就能运行;缺点是默认不支持JSP,需要优化定制时比较复杂(需要用到ServerPropertiesEmbeddedServletContainerCustomizer或自己编写嵌入式Servlet容器的创建工厂)。使用外置的Servlet容器,即在外部安装Tomcat,应用war包的形式打包。

4.1 配置外部Servlet容器

首先需要创建一个打war包的SpringBoot项目,并且手动创建src\main\webapp目录和web.xml文件。

在这里插入图片描述
然后引入自己外部的tomcat。
在这里插入图片描述

4.2 使用外部Servlet容器的步骤

第一步:创建一个war项目(利用idea创建好目录结构)

第二步:将嵌入式的Tomcat指定为provided。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐tomcat</artifactId>
	<scope>provided</scope>
</dependency>

第三步:编写一个SpringBootServletInitializer的子类,并调用configure方法。
该步骤IDEA帮助我们自动完成了。

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    	 //传入SpringBoot应用的主程序
        return application.sources(SpringBoot04WebJspApplication.class);
    }
}

第四步:启动服务器就可以使用。

原创文章 475 获赞 1731 访问量 58万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/106128254