熵增学院-Anders-剑走偏锋,了解Spring Boot内部Servlet容器

还记得大明湖畔的servlet吗?其实Spring Boot支持内嵌的Tomcat, Jetty和Undertow服务器,多数开发者只须要使用合适的'Starter'来获取一个彻底配置好的实例便可,内嵌服务器默认监听8080端口的HTTP请求。java

这样子是否是以为很简单,很方便,有种开发nodejs的感受.....node

 

1. 在SpringBoot中还有Servlets, Filters和listeners吗?

使用内嵌servlet容器时,你能够经过使用Spring beans或扫描Servlet组件的方式注册Servlets,Filters及特定Servlet相关的全部listeners(好比HttpSessionListener)。web

将Servlets,Filters和listeners注册为Spring beansspring

全部ServletFilter或Servlet *Listener实例,只要是Spring bean,都会注册到内嵌容器中。若是想在配置期间引用application.properties的属性,这是很是方便的。默认状况下,若是上下文只包含单个Servlet,那它将被映射到/。若是存在多个Servlet beans,那么bean的名称将被用做路径的前缀,过滤器将映射到/*json

若是基于约定(convention-based)的映射不够灵活,你可使用ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean实现彻底的控制。tomcat

 

1 建立servlet服务器

package com.gala.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {    
  private static final long serialVersionUID = -2646554587718007415L;    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        
    // 设置返回类型为json
        resp.setContentType("application/json");        
        // 设置返回字符集
        resp.setCharacterEncoding("UTF-8");        
        // 输出对象
        PrintWriter writer = resp.getWriter();        
        // 输出error消息
        writer.write("成功执行doGet方法");
        writer.close();
    }
}

2 使用Bean注册Servlet(单个Servlet)cookie

package com.gala.servlet.conf;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.gala.servlet.TestServlet;
@Configuration
public class ServletConfiguration {    
        @Bean
    public ServletRegistrationBean<TestServlet> servletRegistrationBean() {        
        return new ServletRegistrationBean<TestServlet>(new TestServlet(), "/test");
    }
}

 

SpringBoot自动装配Servlet(多个Servlet)网络

 

SpringBoot内部提供了注解@ServletComponentScan,这个注解的做用就是自动扫描咱们SpringBoot项目内的有关Servlet配置,自动装配到咱们的项目中。session

 

TestServlet须要与ServletConfiguration同目录或在其子目录中

 

修改ServletConfiguration,增长@ServletComponentScan

package com.gala.servlet.conf;

import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ServletComponentScan
public class ServletConfiguration {

}

修改TestServlet,增长@WebServlet(urlPatterns = "/test2")

package com.gala.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/test2")
public class TestServlet extends HttpServlet {

    private static final long serialVersionUID = -2646554587718007415L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置返回类型为json
        resp.setContentType("application/json");
        // 设置返回字符集
        resp.setCharacterEncoding("UTF-8");
        // 输出对象
        PrintWriter writer = resp.getWriter();
        // 输出error消息
        writer.write("成功执行doGet方法");
        writer.close();
    }
}

 

 

2. 在Filters和listeners怎么使用

 

内嵌servlet容器不会直接执行Servlet 3.0+的javax.servlet.ServletContainerInitializer接口,或Spring的org.springframework.web.WebApplicationInitializer接口,这样设计的目的是下降war包内运行的第三方库破坏Spring Boot应用的风险。

若是须要在Spring Boot应用中执行servlet上下文初始化,你须要注册一个实现org.springframework.boot.context.embedded.ServletContextInitializer接口的bean。onStartup方法能够获取ServletContext,若是须要的话能够轻松用来适配一个已存在的WebApplicationInitializer。

扫描Servlets, Filters和listeners

当使用一个内嵌容器时,经过@ServletComponentScan能够启用对注解@WebServlet,@WebFilter和@WebListener类的自动注册。

注 在独立的容器(非内嵌)中@ServletComponentScan不起做用,取为代之的是容器内建的discovery机制。

 

3. 自定义配置servlet容器

 

常见的Servlet容器配置能够经过Spring Environment进行设置,一般将这些属性定义到application.properties文件中。

常见的服务器配置包括:

网络设置:监听进入Http请求的端口(server.port),接口绑定地址server.address等。

Session设置:session是否持久化(server.session.persistence),session超时时间(server.session.timeout),session数据存放位置(server.session.store-dir),session-cookie配置(server.session.cookie.*)。

Error管理:错误页面的位置(server.error.path)等。

SSL。

HTTP压缩

 

Spring Boot会尽可能暴露经常使用设置,但这并不老是可能的。对于不可能的状况,可使用专用的命名空间提供server-specific配置(查看server.tomcat,server.undertow)。例如,能够根据内嵌servlet容器的特性对access logs进行不一样的设置。

注 具体参考ServerProperties。

 

4. 老生常谈的JSP

 

当使用内嵌servlet容器运行Spring Boot应用时(并打包成一个可执行的存档archive),容器对JSP的支持有一些限制

Tomcat只支持war的打包方式,不支持可执行jar。

Jetty只支持war的打包方式。

Undertow不支持JSPs。

建立的自定义error.jsp页面不会覆盖默认的error handling视图。

本文相关视频

相关文章
相关标签/搜索