您的位置:首页 > 编程语言 > Java开发

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

2018-11-09 15:25 429 查看

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

这样子是不是觉得很简单,很方便,有种开发nodejs的感觉.....

 

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

使用内嵌servlet容器时,你可以通过使用Spring beans或扫描Servlet组件的方式注册Servlets,Filters及特定Servlet相关的所有listeners(比如HttpSessionListener)。

将Servlets,Filters和listeners注册为Spring beans

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

如果基于约定(convention-based)的映射不够灵活,你可以使用ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean实现完全的控制。

 

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)

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配置,自动装配到我们的项目中。

 

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视图。

本文相关视频

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息