23.Spring-Boot中Servlet容器的支持

      Spring Boot中内嵌了Tomcat、Jetty和Undertow服务器。大多数开发人员将只需使用适当的“启动器”来获得一个完全配置的实例。默认情况下,内嵌的服务器HTTP请求监听8080端口。

    注意:如果您选择在CentOS上使用Tomcat,请注意,默认情况下,临时目录是。用于存储已编译的jsp、文件上传等。当应用程序运行导致失败时,该目录可以就被tmpwatch删除。为了避免这一点,您可能需要定制您的tmpwatch配置。通过使用server.tomcat.basedir来配置内嵌的Tomcat。

关于servlet、 Filters、listeners

       在使用嵌入式servlet容器时,您可以注册servlet、 Filters、listeners 。Servlet规范要么使用Spring bean,要么通过扫描Servlet组件。

1.通过Spring Bean注册servlet、 Filters、listeners

默认情况下,如果上下文只包含一个Servlet,它将被映射到/。在多个情况下。Servlet bean bean的名称将用作路径前缀。过滤器将映射到/*。

如果觉得默认的不够灵活可以通过ServletRegistrationBean,FilterRegistrationBean和ServletListenerRegistrationBean 进行注册

@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(logFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;

}

2.通过扫描

当使用嵌入式容器时,可以自动注册@WebServlet、@WebFilter和@WebListener注解类。通过@ServletComponentScan进行扫描.

如:创建filter 在com.niugang.filter包下配置@WebFilter

package com.niugang.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//配置filter拦截的路径
@WebFilter(urlPatterns="/index/*")
public class LogFilter implements javax.servlet.Filter{

private static Logger logger = LoggerFactory.getLogger(LogFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String initParameter = filterConfig.getInitParameter("filter-params");
System.out.println("initParameter:"+initParameter);
// TODO Auto-generated method stub
logger.info("初始化filter");
}

    @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req =(HttpServletRequest)request;
HttpServletResponse resp =(HttpServletResponse)response;
logger.info("执行filter................");
chain.doFilter(req, resp);

}
@Override
public void destroy() {
logger.info("filter被销毁");
}

}

配置@ServletComponentScan扫面@WebFilter,在com.niugang.config包下

package com.niugang.config;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * 扫配置的filter
 * @author niugang
 *
 */
@ServletComponentScan(basePackages="com.niugang.filter")
@Configuration
public class FilterCompentConfig {


}

初始化Servlet上下文

嵌入式servlet容器不会直接执行servlet。3.0 + javax.servlet.ServletContainerInitializer接口和Spring的

org.springframework.web.WebApplicationInitializer接口。这是一个故意旨在减少第三方库在运行中对springboot程序带来的危害。

如果您需要启动应用程序时在Spring中执行servlet上下文初始化,您应该注册bean实现

org.springframework.boot.context.embedded.ServletContextInitializer 接口,此接口中只有一个单一的onStartup方法提供了对ServletContext的访问,并且很容易适配已存在的WebApplicationInitializer 。

package com.niugang.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.stereotype.Component;
@Component
public class ServletConfig implements ServletContextInitializer {
        @Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("容器启动.................");
}

}

启动项目打印日志如下:

EmbeddedWebApplicationContext

Spring Boot内嵌的servlet容器使用了一种新类型的ApplicationContext。EmbeddedWebApplicationContext是一种特殊WebApplicationContext 类型,靠自己寻找一个EmbeddedServletContainerFactory bean。通常是一个TomcatEmbeddedServletContainerFactory JettyEmbeddedServletContainerFactory,或UndertowEmbeddedServletContainerFactory这些已经自动配置过了。

注:

您通常不需要实现类上面这些类,大多数应用程序将自动配置和适当的创建ApplicationContext和EmbeddedServletContainerFactory。

自定义嵌入servlet容器

只需要在application.properties中配置=

网络配置:server.port服务端口 server.addres服务地址

session设置:session是否持久化server.session.persistence,server.session.timeout session超时设置

server.session.store-dir session存储的文件,server.session.cookie.* cookie相关配置

错误相关:server.error.path 错误页面路径

除了以上还有其他点击查看

通过编程自定义嵌入servlet容器

如果需要以编程方式配置嵌入的servlet容器,则可以。注册一个Spring bean实现EmbeddedServletContainerCustomizer接口。EmbeddedServletContainerCustomizer提供访问ConfigurableEmbeddedServletContainer包括许多定制setter方法。

import org.springframework.boot.context.embedded.*;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
           container.setPort(9000);

    }

}

直接通过@Bean注解形式

如果以上的定制技术太有限,您可以注册。TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory 来实现。

@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
   factory.setPort(9000);
    factory.setSessionTimeout(10, TimeUnit.MINUTES);
    factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
   return factory;

}

JSP的限制

在sringboot应用程序中使用内嵌的servlet容器对于jsp的支持有太多的限制。

  • 如果用war在tomcat中是可以正常运行的,但是如果是一个可执行的jar包在tomcat中不能运行,因为它是一个硬编码文件,tomcat运行的是编译后的文件。
  • war在jetty中是可以运行的,可以发布到标准中容器中。
  • Undertow是不支持jsp的
  • 自定义的error.jsp将不会覆盖替代默认的错误处理器。

     微信公众号

     

     

原文地址:https://www.cnblogs.com/niugang0920/p/12196421.html