还记得大明湖畔的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
所有Servlet
,Filter
或Servlet *Listener
实例,只要是Spring bean,都会注册到内嵌容器中。如果想在配置期间引用application.properties
的属性,这是非常方便的。默认情况下,如果上下文只包含单个Servlet,那它将被映射到/
。如果存在多个Servlet beans,那么bean的名称将被用作路径的前缀,过滤器将映射到/*
。
如果基于约定(convention-based)的映射不够灵活,你可以使用ServletRegistrationBean
,FilterRegistrationBean
,ServletListenerRegistrationBean
实现完全的控制。
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视图。
来源:oschina
链接:https://my.oschina.net/u/3917355/blog/2874150