什麼是Servlet?
Servlet是一種基於Java技術的Web組件,用於生成動態內容,由容器管理。類似於其他Java技術組件,Servlet是平臺無關的Java類組成,並且由Java Web服務器加載執行
什麼是Servlet容器?
Servlet 容器,有時候也稱作爲 Servlet 引擎,作爲Web服務器或應用服務器的一部分。通過請求和響應對話,提供 Web 客戶端與 Servlets 交互的能力。容器管理Servlets實例以及它們的生命週期。
Servlet 3.0前時代
服務組件
- javax.servlet.Servlet
- javax.servlet.Filter(since Servlet 2.3)
上下文組件
- javax.servlet.ServletContext
- javax.servlet.http.HttpSession(服務端)
- javax.servlet.http.HttpServletRequest
- javax.servlet.http.HttpServletResponse
- javax.servlet.http.Cookie(客戶端)
配置
- javax.servlet.ServletConfig
- javax.servlet.FilterConfig(since Servlet 2.3 )
輸入輸出(二進制輸入和輸出)
- javax.servlet.ServletInputStream
- javax.servlet.ServletOutputStream
異常
- javax.servlet.ServletException
事件
生命週期類型
- javax.servlet.ServletContextEvent
- javax.servlet.http.HttpSessionEvent
- java.servlet.ServletRequestEvent
屬性上下文類型
- javax.servlet.ServletContextAttributeEvent
- javax.servlet.http.HttpSessionBindingEvent
- javax.servlet.ServletRequestAttributeEvent
監聽器(since Servlet 2.3)
生命週期類型
- javax.servlet.ServletContextListener
- javax.servlet.http.HttpSessionListener
- javax.servlet.http.HttpSessionActivationListener
- javax.servlet.ServletRequestListener
屬性上下文類型
- javax.servlet.ServletContextAttributeListener
- javax.servlet.http.HttpSessionAttributeListener
- javax.servlet.http.HttpSessionBindingListener
- javax.servlet.ServletRequestAttributeListener
Servlet 3.0後時代
組件申明註解
@javax.servlet.annotation.WebServlet
@javax.servlet.annotation.WebFilter
@javax.servlet.annotation.WebListener
下面是權限和安全
@javax.servlet.annotation.ServletSecurity
@javax.servlet.annotation.HttpMethodConstraint
@javax.servlet.annotation.HttpConstraint
配置申明
@javax.servlet.annotation.WebInitParam
上下文
javax.servlet.AsyncContext
事件
javax.servlet.AsyncEvent
監聽器
javax.servlet.AsyncListener
Servlet 組件註冊
javax.servlet.ServletContext#addServlet()
javax.servlet.ServletRegistration
Filter 組件註冊
javax.servlet.ServletContext#addFilter()
javax.servlet.FilterRegistration
監聽器註冊
javax.servlet.ServletContext#addListener()
javax.servlet.AsyncListener
自動裝配
初始器
javax.servlet.ServletContainerInitializer
類型過濾
@javax.servlet.annotation.HandlesTypes
Servlet 生命週期
一般情況不會直接實現Servlet接口,而是繼承HttpServlet接口,他的service方法會獲取當前http請求的方法,然後調用對應的doGet/doHead/doPost/doPut/doDelete/doOptions方法
初始化
當容器啓動或者第一次執行時,Servlet#init(ServletConfig)方法被執行,初始化當前Servlet 。
處理請求
當HTTP 請求到達容器時,Servlet#service(ServletRequest,ServletResponse) 方法被執行,來處理請求。
銷燬
當容器關閉時,容器將會調用Servlet#destroy 方法被執行,銷燬當前Servlet。
Filter 生命週期
初始化
當容器啓動時,Filter#init(FilterConfig)方法被執行,初始化當前Filter。
處理請求
當HTTP 請求到達容器時,Filter#doFilter(ServletRequest,ServletResponse,FilterChain) 方法被執行,來攔截請求,在Servlet#service(ServletRequest,ServletResponse) 方法調用前執行。
銷燬
當容器關閉時,容器將會調用Filter#destroy 方法被執行,銷燬當前Filter。
Servlet On Spring Boot
Servlet 組件掃描
@org.springframework.boot.web.servlet.ServletComponentScan
指定包路徑掃描
String[] value() default {}
String[] basePackages() default {}
指定類掃描
Class<?>[] basePackageClasses() default {}
註解方式註冊
Servlet組件
1.擴展 javax.servlet.Servlet
javax.servlet.http.HttpServlet
org.springframework.web.servlet.FrameworkServlet
2.標記 @javax.servlet.annotation.WebServlet
Servlet
Filter組件
實現 javax.servlet.Filter
org.springframework.web.filter.OncePerRequestFilter
標記 @javax.servlet.annotation.WebFilter
監聽器
監聽器組件
實現Listener接口
javax.servlet.ServletContextListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionActivationListener
javax.servlet.ServletRequestListener
javax.servlet.ServletContextAttributeListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionBindingListener
javax.servlet.ServletRequestAttributeListener
標記 @javax.servlet.annotation.WebListener
SpringBootLearnApplication
@SpringBootApplication
@ServletComponentScan(basePackages = {"com.yun.springbootlearn.servlet"})
public class SpringBootLearnApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringBootLearnApplication.class, args);
System.out.println("start");
}
}
MyFilter
@WebFilter(urlPatterns = "/myservlet")
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
ServletContext context = request.getServletContext();
context.log("/myservlet was filtered");
filterChain.doFilter(request,response);
}
}
MyServlet
@WebServlet(
name = "myServlet",
urlPatterns = "/myservlet",
initParams ={
@WebInitParam(name = "myname", value = "myvalue")
}
)
public class MyServlet extends HttpServlet {
private String value;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
value = servletConfig.getInitParameter("myname");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer writer = resp.getWriter();
//是通過super.init(servletConfig)初始化好纔可以得到ServletContent
ServletContext context = getServletContext();
context.log("myServlet do get");
writer.write("<html><body>Hello,World“”“"+value+"</body></html>");
}
}
MyListener
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
ServletContext context = request.getServletContext();
context.log("request was initialized");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
ServletContext context = request.getServletContext();
context.log("request was destoryed");
}
}
Spring Boot API方式註冊
Servlet 組件
1.擴展 javax.servlet.Servlet
javax.servlet.http.HttpServlet
org.springframework.web.servlet.FrameworkServlet
2.組裝 Servlet
Spring Boot 1.4.0 開始支持
org.springframework.boot.web.servlet.ServletRegistrationBean
Spring Boot 1.4.0 之前
org.springframework.boot.context.embedded.ServletRegistrationBean
3.暴露 Spring Bean
@Bean
Filter 組件
1.實現 javax.servlet.Filter
org.springframework.web.filter.OncePerRequestFilter
2.組裝 Filter
Spring Boot 1.4.0 開始
org.springframework.boot.web.servlet.FilterRegistrationBean
Spring Boot 1.4.0 之前
org.springframework.boot.context.embedded.FilterRegistrationBean
3.暴露 Spring Bean
@Bean
監聽器組件
1.實現 Listener
2.組裝 Listener
Spring Boot 1.4.0 開始
org.springframework.boot.web.servlet.ServletListenerRegistrationBean
Spring Boot 1.4.0 之前
org.springframework.boot.context.embedded.ServletListenerRegistrationBean
3.暴露 Spring Bean
@Bean
MyServlet2
public class MyServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer writer = resp.getWriter();
//是通過super.init(servletConfig)初始化好纔可以得到ServletContent
ServletContext context = getServletContext();
context.log("myServlet do get 2");
writer.write("<html><body>Hello,World“”“ from myservlet2</body></html>");
}
}
MyFilter2
public class MyFilter2 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();
String requestURI = request.getRequestURI();
servletContext.log(requestURI + " was filtered!");
}
}
SpringBootLearnApplication
@SpringBootApplication
@ServletComponentScan(basePackages = {"com.yun.springbootlearn.servlet"})
public class SpringBootLearnApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringBootLearnApplication.class, args);
System.out.println("start");
}
@Bean
public static ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new MyServlet2());
servletRegistrationBean.setName("my-servlet2");
servletRegistrationBean.addUrlMappings("/spring-boot/myservlet2");
servletRegistrationBean.addInitParameter("myname","myvalue");
return servletRegistrationBean;
}
@Bean
public static FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter2());
filterRegistrationBean.addServletNames("my-servlet2");
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.FORWARD,DispatcherType.INCLUDE);
return filterRegistrationBean;
}
@Bean
public static ServletListenerRegistrationBean servletListenerRegistrationBean() {
ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean();
servletListenerRegistrationBean.setListener(new MyServletRequestListener());
return servletListenerRegistrationBean;
}
}
激活 傳統Servlet Web部署
1.需要引入相應的依賴
<!-- JSP 渲染引擎 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
2.修改打包方式爲war包
<packaging>war</packaging>
3.Spring Boot 1.4.0 開始 繼承
org.springframework.boot.web.support.SpringBootServletInitializer
@SpringBootApplication
@ServletComponentScan(basePackages = {"com.yun.springbootlearn.servlet"})
public class SpringBootLearnApplication extends SpringBootServletInitializer {
}
4.組裝 org.springframework.boot.builder.SpringApplicationBuilder
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
builder.sources(SpringBootLearnApplication.class);
return builder;
}
5.配置JSP視圖 在application.properties
org.springframework.boot.autoconfigure.web.WebMvcProperties
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp