Spring Boot学习4:web篇(下)-Spring boot (Servlet,Jsp)学习

1.传统Servlet回顾
什么是Servlet:小服务端应用,是一种基于Java的web组件,用于生成动态内容,由容器管理。servlet是平台无关的java类组成,并且由Java web服务器加载执行


什么是Servlet容器?

Filter生命周期

Servlet生命周期

2.Servlet On Spring Boot
1)Servlet组件扫描
org.springframework.boot.web.servlet.ServletComponentScan
指定包路径扫描
指定类扫描



2)注解方式注册
2.1)Servlet

2.1.1)Servlet组件扫描
例1:创建项目spring-boot-lesson-4
创建一个包servlet,创建一个Servlet:MyServlet,并继承HttpServlet

@WebServlet(
        name="myServlet",   //servlet名称
        urlPatterns = "/myServlet"  //url映射路径
)
public class MyServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Writer writer = resp.getWriter();
        writer.write("<html><body><h1>hello world</h1></body></html>");
        //super.doGet(req, resp);
    }
}


然后在SpringBoot的启动程序SpringBootLesson4Application中,扫描Servlet组件进行注册

@SpringBootApplication
@ServletComponentScan(basePackages = {"servlet"})
public class SpringBootLesson4Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLesson4Application.class, args);
    }
}


启动Spring Boot访问localhost:8080/myServlet,就可以看到Hello World显示在界面上



2.1.2)如果希望加上初始化参数呢?
        initParams = {
                @WebInitParam(name="myName", value="myValue" )
        }
例2:
@WebServlet(
        name="myServlet",
        urlPatterns = "/myServlet",
        initParams = {
                @WebInitParam(name="myName", value="myValue" )
        }
)
public class MyServlet extends HttpServlet {

    private String value;
    @Override
    public void init(ServletConfig config) throws ServletException {
        value = config.getInitParameter("myName");
    }

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Writer writer = resp.getWriter();
        writer.write("<html><body><h1>hello world</h1><br/><h2>myValue:"+value+"</h2></body></html>");

        //super.doGet(req, resp);
    }
}

2.2)Filter
OncePerRequestFilter:这是一个实现Filter的抽象类
例1:创建包,创建Filter类:MyFilter,并实现OncePerRequestFilter
我们可以针对某个Servlet进行过滤
servletNames="myServlet"
和urlPattern = "/myServlet" 两者的配置效果是一样的,一个是servletName的过来,一个是url的过来

@WebFilter(
        servletNames= "myServlet"
)
public class MyFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        servletContext.log("/myServlet is filting");
        filterChain.doFilter(request,response);
    }
}


修改Spring Boot启动程序上的扫描包,添加Filter包的扫描,或者扩大扫描范围

@SpringBootApplication
@ServletComponentScan(basePackages = {"com/segmentfault"})
public class SpringBootLesson4Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLesson4Application.class, args);
    }
}



刷新3次,就有3次日志:
2018-02-06 14:32:46.900  INFO 8232 --- [nio-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myServlet is filting
2018-02-06 14:32:47.088  INFO 8232 --- [nio-8080-exec-5] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myServlet is filting
2018-02-06 14:32:47.289  INFO 8232 --- [nio-8080-exec-9] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myServlet is filting

2.3)监听器
实现Request的监听,

例子:

@WebListener
public class MyServletRequestListener implements ServletRequestListener {

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        ServletContext servletContext = sre.getServletContext();
        servletContext.log("/myListener is initialized..");
    }
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        ServletContext servletContext = sre.getServletContext();
        servletContext.log("/myListener is destroyed..");
    }

}

运行程序:我们可以看出servlet,filter和listener执行的顺序,并且都是在一个线程中执行的。
2018-02-08 10:19:46.576  INFO 20224 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myListener is initialized..
2018-02-08 10:19:46.578  INFO 20224 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myServlet is filting
2018-02-08 10:19:46.578  INFO 20224 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myServlet is doGet...
2018-02-08 10:19:46.578  INFO 20224 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myListener is destroyed..



3)Spring Boot API方式注册

创建spring.segmentfault.setvlet,spring.segmentfault.filter,spring.segmentfault.listener三个包
并创建3个类Servlet2,Filter2,Listener2
public class Servlet2 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        servletContext.log("myServlet2 doGet...");
        Writer writer = resp.getWriter();
        writer.write("hello world2");
    }
}



public class Filter2 extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        servletContext.log("/myFilter2 is filtering");
        filterChain.doFilter(request,response);
    }
}



public class Listener2 implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        ServletContext servletContext = sre.getServletContext();
        servletContext.log("myListener2 is destroyed");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        ServletContext servletContext = sre.getServletContext();
        servletContext.log("myListener2 is initialized");
    }
}


在springboot启动程序中,我们可以注册servlet,filter,listener组件

@SpringBootApplication
@ServletComponentScan(basePackages = {"com/segmentfault"})
public class SpringBootLesson4Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLesson4Application.class, args);
    }


    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
        servletRegistrationBean.setName("myServlet2");
        servletRegistrationBean.setServlet(new Servlet2());
        servletRegistrationBean.addUrlMappings("/spring/myServlet2");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new Filter2());
        filterRegistrationBean.setName("myFilter2");
        filterRegistrationBean.addServletNames("myServlet2");
        //设置请求方式过滤
        filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.FORWARD,DispatcherType.INCLUDE);
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean(){
        ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean();
        servletListenerRegistrationBean.setListener(new Listener2());
        return servletListenerRegistrationBean;
    }
}



此时我们访问http://localhost:8080/spring/myServlet2
控制台打印,这样我们就实现了spring boot api方式注册servlet,filter,listener组件
2018-02-08 10:13:02.857  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : myListener2 is initialized
2018-02-08 10:13:02.858  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myListener is initialized..
2018-02-08 10:13:02.860  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myFilter2 is filtering
2018-02-08 10:13:02.860  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : myServlet2 doGet...
2018-02-08 10:13:02.860  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : /myListener is destroyed..
2018-02-08 10:13:02.861  INFO 7648 --- [nio-8080-exec-8] o.a.c.c.C.[Tomcat].[localhost].[/]       : myListener2 is destroyed






对于RequestContextHolder的理解
里面存储着ServletRequestAttribute,放在ThreadLocal中,这样,在一个线程中都可以获取到同一个对象,同时,在request结束的时候,就会销毁ThreadLocal中的对象
局部源码:
public abstract class RequestContextHolder  {

    private static final boolean jsfPresent =
            ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());

    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
            new NamedThreadLocal<RequestAttributes>("Request attributes");

    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
            new NamedInheritableThreadLocal<RequestAttributes>("Request context");


销毁的时候:

/**
 * Reset the RequestAttributes for the current thread.
 */
public static void resetRequestAttributes() {
    requestAttributesHolder.remove();
    inheritableRequestAttributesHolder.remove();
}



例子:我们在Filter2加一个方法doSomething,在方法中通过RequestContextHolder获取到request对象,并进行相关操作

public class Filter2 extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        doSomething();
        filterChain.doFilter(request,response);
    }

    public void doSomething(){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        ServletContext servletContext = request.getServletContext();
        servletContext.log(request.getRequestURI()+" is filtering");
    }
}




3.JSP On Spring Boot
springboot建议使用模板引擎开发,jsp在spring boot中是受限制的,所以我们需要激活
激活:
1)实现
让SpringBootLesson4Application继承SpringBootServletInitializer,并重写configure方法,

//组装工作
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    builder.sources(SpringBootLesson4Application.class);
    return builder;
}

2)添加依赖

<!--jsp 渲染引擎-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>


3)





4.Q&A

1)SpringBoot作为web容器时候与spring3时候性能提升多少?

2)我还在使用1.3版本,有必要升级到1.5吗?坑多吗?logback就是个坑!
不建议升级到1.5版本,至少LoggingSystem中的某个标记去了,导致logback这个坑,并且去除了log4j1
另外,还有Velocity也去除了。
如果需要升级,建议升级到2.0版本

3)SpringBoot对于注解的方式,大项目怎么样?好管理吗?
SpringBoot是使用自动装配的方式做的,其实SpringBoot在初始化的时候,装配了大量的类、组件等
可以看spring.factories的autoconfigure,可以看到自动装配的组件很多,大部分我们听也没听过

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnClassCondition

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer

# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider



InternalViewResolver是在WebMvcAutoConfiguration




3)springboot会不会有spring和springmvc关于父子容器aop失效的问题
springboot是有一个main程序启动类,和以前的方式不太一样。
springmvc是dispatcherServlet上下文创建的,
而springboot是将dispatcherServlet作为一个组件创建的



4)













  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值