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)
什麼是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)
相關文章
- Spring Boot學習3:web篇(中)-Spring boot Rest學習Spring BootWebREST
- Spring Boot學習5:spring-boot web容器Spring BootWeb
- spring boot學習Spring Boot
- Spring Boot 學習Spring Boot
- Spring Boot學習6:Spring Boot JDBCSpring BootJDBC
- Spring Boot學習之---Spring Boot與檢索 下(十六)Spring Boot
- Spring Boot學習(一)——Spring Boot介紹Spring Boot
- Spring boot學習(三) Spring boot整合mybatisSpring BootMyBatis
- Spring boot學習(二) Spring boot基礎配置Spring Boot
- Spring boot學習(四)Spring boot整合DruidSpring BootUI
- Spring boot學習(一)開啟Spring boot之旅Spring Boot
- Spring Boot學習筆記:Spring Boot核心配置Spring Boot筆記
- spring boot學習(4): 命令列啟動Spring Boot命令列
- spring boot學習4 多環境配置Spring Boot
- Spring Boot 學習目錄Spring Boot
- Spring Boot 學習-基礎Spring Boot
- Spring boot學習(九)Spring boot配置郵件傳送Spring Boot
- Spring boot學習(八)Spring boot配置ehcache快取框架Spring Boot快取框架
- Spring boot學習(五)Spring boot整合Mybatis Generator以及PageHelperSpring BootMyBatis
- Spring Boot 學習筆記(4):配置properties(1)Spring Boot筆記
- Spring Boot 學習筆記(4):配置properties(2)Spring Boot筆記
- Spring Boot + JPA學習總結Spring Boot
- 什麼是Spring Boot?為什麼要學習Spring Boot?Spring Boot
- Spring Boot 學習資料 (轉載)Spring Boot
- Spring Boot 學習筆記(2):JDBCSpring Boot筆記JDBC
- Spring Boot 學習筆記(3):MyBatisSpring Boot筆記MyBatis
- Spring boot + Zookeeper + Dubbo學習筆記Springboot筆記
- Java Spring Boot 學習筆記(一)JavaSpring Boot筆記
- Spring Boot學習資料彙總Spring Boot
- 快速學習 Spring Boot 技術棧Spring Boot
- Spring boot學習(六)Spring boot實現AOP記錄操作日誌Spring Boot
- Spring Boot 學習 (1): 初始化工程Spring Boot
- Spring Boot--日誌框架的學習Spring Boot框架
- spring boot學習與踩坑記錄Spring Boot
- Spring Boot 學習筆記(1):快速上手Spring Boot筆記
- spring boot學習簡要筆記1Spring Boot筆記
- Spring Boot學習筆記---Spring Boot 基礎及使用idea搭建專案Spring Boot筆記Idea
- spring boot學習(5): 程式exit code自定義Spring Boot