《Head First Servlet&JSP》讀書筆記

《Head First Servlet&JSP》讀書筆記

本身最近在看《How Tomcat Works》這本書。Tomcat是Servlet容器,在這本書裏面大量使用到了Servlet,可是本身對Servlet不是好清晰,因此花了2天時間讀了這本書。html

1. 概述

1.1 總結
整體的來講,《Head First Servelt&JSP》這本書仍是很是不錯的,對Servlet&Jsp介紹的挺細的且有主次區分,讓人理解起來輕鬆。由於《Head First》系列都是經過半漫畫形式講解,因此書較厚,不過讀起來輕鬆。由於本身以前就瞭解Servelt&Jsp,因此讀起來挺快的。web

1.2 目錄spring

  1. 爲何使用Servlet&Jsp
  2. Web應用體系框架
  3. MVC迷你教程
  4. 做爲Servlet
  5. 做爲Web應用
  6. 會話狀態
  7. 做爲JSP
  8. 沒有腳本的頁面
  9. 強大的定製標記
  10. JSTL也有力不及的時候...
  11. 部署Web應用
  12. 要保密,要安全
  13. 過濾器的威力
  14. 企業設計模式

本身看了第一、二、三、四、五、六、七、十一、1三、14章。關於JSP方面本身看的較少,一來本身以爲如今流行先後端分離,使用JSP技術應該愈來愈少;二來本身就不喜歡類型View方面的東西,仍是喜歡代碼 ^ - ^後端

1.3 章節解釋
第一章(爲何使用Servlet&Jsp):主要解釋了Web客戶端、服務器作了什麼,以及它們之間的通訊:HTTP協議。
第2、三章(Web應用體系框架、MVC迷你教程):我的以爲這一章講的挺好的,也挺有用的。尤爲對於知道怎麼使用Servlet&Jsp或者使用Servlet框架(SpringMVC或Struts2),它將會讓你瞭解整個Java Web的大致框架。如:一個HTTP請求的大致流程是什麼樣的;Web.xml的做用;爲何Web-INFO下是安全目錄等等。
第四章(做爲Servlet):主要講了Servlet的生命週期、Servlet如何處理請求等等。
第五章(做爲Web應用):主要講了ServletConfig與ServletContext、8個監聽器的使用、以及4個對象(ServletContext、ServletRequest 、ServletResponse、HttpSession)的生命週期、線程安全、做用域等等。
第六章(會話狀態):主要講了會話如何工做、如何建立、如何添加屬性等等。
第七章(做爲JSP):主要講了JSP與Servlet的關係,一些JSP的基本用法等等。
第十一章(部署Web應用):主要講了把Java Web項目部署到Servlet容器中使用(如Tomcat),與第一二章食用更佳。
第十三章(過濾器的威力):主要講了Servlet中的Filter(過濾器)的使用。
第十四章(企業設計模式):講了講企業開發中的一些組件、以及Struts的MVC模式(有點老了,如今版本與它說的都不同了)。設計模式

2. 一些總結吧


2.1 什麼是容器?
容器是用來部署Servlet的容器,處理一切與Servelt相關的請求。若是Web服務器應用(如Apache)獲得一個指向Servelt的請求(而不是其它請求,如請求靜態資源),這時服務器會把該請求交給部署該Servlet的容器,由容器向Servlet提供請求與響應對象,調用Servlet的service()方法處理請求。注:Tomcat實際上Web服務器與Servlet容器的結合體,它既處理靜態資源請求,也處理Servelt請求。安全

2.2 容器能提供什麼?服務器

  • 通訊支持:Servlet不直接與客戶端通訊,而是由容器與客戶端進行通訊。因此Servlet中只須要寫業務邏輯(解耦)。
  • Servlet生命週期的管理:注每一個Servlet在容器中只有一個實例。
  • 多線程的支持:容器會自動爲每一個請求分配一個線程,並處理它。
  • JSP的支持:會把JSP自動編譯爲Servlet,並管理它。

2.3 容器如何管理Servletsession

  • 容器會加載web.xml文件初始化一些信息(如Servelt與URL的對應關係),信息保存在ServletContext對象中。也就是說一個web.xml對應一個ServeltContext對象。
  • 容器會在請求到來以前實例化Servlet並初始化一些信息,可經過loadOnStartup字段配置何時實例化Servelt。
  • 容器調用Servelt的init()方法處理化一些信息,如配置Servlet時的init-Param信息。這些信息在ServletConfig對象中。也就是說每一個Servlet都有本身對應的ServletConfig對象。
  • 容器會在請求到來時建立一個ServletRequest、ServletResponse對象,分配一個線程,調用對應的Servlet對象的service()方法進行處理。注意:Servlet只有一個對象實例,容器會爲每一個請求分配線程並調用Servlet的service(ServletReqeust req, ServletResponse resp)方法進行處理。
  • 容器調用Servlet的destory()方法進行銷燬Servlet。

2.4 ServletContext與ServletConfigmybatis

  • ServeltContext應該叫作WebContext更好,它表明一個Web程序的上下文。咱們能夠在web.xml文件中context-param字段中初始化一些數據,但這些數據是線程不安全的。
  • ServletConfig表明Servelt配置的一些信息。其在Servlet的init(ServletConfig config)方法中進行初始化。在SSM框架中,咱們就會在DispatcherServlet配置中初始化全部的spring容器中的對象。以下:

 

 1 <!-- 配置DispatcherServlet -->
 2 <servlet>
 3     <servlet-name>seckill-dispatcher</servlet-name>
 4     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 5     <!-- 配置springMVC須要加載的配置文件
 6     spring-dao.xml spring-service.xml spring-web.xml
 7     mybatis -> spring -> springMVC-->
 8     <init-param>
 9         <param-name>contextConfigLocation</param-name>
10         <param-value>classpath:spring/spring-*.xml</param-value>
11     </init-param>
12     <load-on-startup>1</load-on-startup>
13 </servlet>
14 <servlet-mapping>
15     <servlet-name>seckill-dispatcher</servlet-name>
16     <!-- 默認匹配全部的請求 -->
17     <url-pattern>/</url-pattern>
18 </servlet-mapping>

 

2.5 Servlet多線程

  • Servlet的生命週期能夠看上面的:容器如何管理Servlet。
  • Servlet處理請求時,容器經過調用其service()方法來處理請求,而service()方法經過查詢Http的請求方法來調用對於的Servlet方法,如GET-->doGet(),POST-->doPost()。因此咱們寫Servlet時,須要繼承HttpServlet,而後重寫其doGet()、doPost()或doDelete()等方法,具體要看該Servlet處理什麼請求方法。

注:Servlet須要在web.xml中註冊

2.6 請求與響應

  • 容器會在HTTP請求到來時建立ServletRequest、ServletResponse對象。請求的全部信息都會保存在ServletRequest對象中,具體看它的API。響應的信息(包括響應頭)都會寫入ServletResponse對象。注:咱們在使用ServletResponse對象直接發送給客戶端消息時,必須設置Content-Type信息,不然客戶端不可以解析該信息。

 

 1 @WebServlet(loadOnStartup=1, urlPatterns={"/test"})
 2 public class TestServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         HttpSession session = req.getSession();
 6         Map<String, String[]> map = req.getParameterMap();
 7         System.out.println("HTTP Query String:");
 8         for (Map.Entry<String, String[]> entry : map.entrySet()) {
 9             System.out.print("key: " + Arrays.toString(entry.getValue()));
10             System.out.println(" value: " + Arrays.toString(entry.getValue()));
11     }
12     String content = "<html>\r\n" +
13                 "<head>\r\n" +
14                 "</head>\r\n" +
15                 "<body>\r\n" +
16                 "Hello World" +
17                 "</body>\r\n" +
18                 "</html>";
19         PrintWriter writer = resp.getWriter();
20         resp.setContentType("text/html");
21         writer.write(content);
22         writer.flush();
23     writer.close();
24     }
25 }
26 ----------萌萌的分割線---------
27 Request:
28 GET /test?id=10086&name=kanyuxia HTTP/1.1
29 Host: localhost:8080
30 Connection: keep-alive
31 Cache-Control: max-age=0
32 Upgrade-Insecure-Requests: 1
33 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
34 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
35 Accept-Encoding: gzip, deflate, sdch, br
36 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
37 Cookie: JSESSIONID=jp3o7r8iufda1c2dykdfzlk5t
38 
39 ----------萌萌的分割線--------
40 Response:
41 HTTP/1.1 200 OK
42 Date: Wed, 19 Apr 2017 07:39:58 GMT
43 Content-Type: text/html;charset=ISO-8859-1
44 Transfer-Encoding: chunked
45 Server: Jetty(8.1.14.v20131031)
46 Request Headers
47 view parsed
48 
49 <html>
50 <head>
51 </head>
52 <body>
53 Hello World</body>
54 </html>
55 ----------萌萌的分割線---------
56 server console:
57 HTTP Query String:
58 key: [kanyuxia] value: [kanyuxia]
59 key: [10086] value: [10086]
View Code

 

2.7 重定向與轉發

  • Servelt中的重定向可使用HttpServletResponse的sendRedirect()方法,該方法至關於在響應頭部中設置響應碼30一、響應頭中的Location字段爲重定向字段。
  • Servlet轉發經過HttpServletRequest的getReqeustDispatcher()方法得到RequestDispatcher對象,而後經過該對象轉發請求與響應對象。

具體使用能夠看:《Spring實戰》讀書筆記--SpringMVC之forward與redirect

2.7 監聽器
Servlet中有8下監聽器,以下:

監聽器接口 事件類型
ServletContextListener ServletContextListener
ServletContextAttributeListener ServletContextAttributeEvent
HttpSessionListener HttpSessionEvent
HttpSessionBindingListener HttpSessionBindingEvent
HttpSessionAttributeListener HttpSessionBindingEvent
HttpSessionAcctivatioinListener HttpSessionEvent
ServletRequestListener ServletRequestEvent
ServletRequestAttributeListener ServletRequestAttributeEvent

具體使用看API吧。注:監聽器須要在web.xml中註冊

 1 @WebListener(value="TestListener")
 2 public class TestListener implements HttpSessionListener {
 3     public void sessionCreated(HttpSessionEvent se) {
 4         HttpSession session = se.getSession();
 5         System.out.println("服務器建立了HttpSession, Session Id 爲:" + session.getId());
 6     }
 7     public void sessionDestroyed(HttpSessionEvent se) {
 8     HttpSession session = se.getSession();
 9     System.out.println("服務器銷燬了HttpSession, Session Id 爲:" + session.getId());
10     }
11 }
12 ----------萌萌的分割線---------
13 response:
14 Content-Type:text/html;charset=ISO-8859-1
15 Date:Wed, 19 Apr 2017 07:44:56 GMT
16 Expires:Thu, 01 Jan 1970 00:00:00 GMT
17 Server:Jetty(8.1.14.v20131031)
18 Set-Cookie:JSESSIONID=km2ogboi1e8i184272wq13myz;Path=/
19 Transfer-Encoding:chunked
20 
21 ----------萌萌的分割線---------
22 server console:
23 服務器建立了HttpSession, Session Id 爲:1ttrgbo9io8gs11o9vwic1zvwx

2.8 Session與Cookies
Http協議是無狀態協議,不能都保存相關信息。因此建立了Cookies、Session來保存相關信息。

  • Cookies是保存在保存在客戶端的信息,每次Http請求都會把該URL下的全部Cookies發給服務器,服務器能夠訪問。但其不安全,由於保存在客戶端,用戶能夠自行刪除。服務器能夠在響應頭的Set-Cookies字段中設置Cookies。
  • Session能夠對同一個客戶在必定時間內保存一些信息。Session信息保存在服務器上面的,因此安全。Session是基於Cookies的,服務器第一下使用Session時,會給客戶端發送Set-Cookies: JSESSIONID=***,設置一個SessionId。之後每次客戶端發送請求都會發送該Cookies該服務器,因此服務器就知道該請求是誰的請求。
  • Servlet中HttpSession對象表示會話對象,咱們能夠HttpServletRequest對象的getSession()方法得到HttpSession對象,而後可使用其方法處理相關邏輯。具體能夠查看HttpSession的API。
  • HttpSession能夠設置時間來控制其生命週期,也能夠在web.xml中配置默認的HttpSession生命週期長度。

2.9 JSP

  • JSP會被容器自動轉換、編譯爲Servlet類,因此其與Servlet類沒有多大的區別。

3.0 過濾器 Filter
咱們能夠配置Filter攔截請求,Filter與Struts2中的Intercept原理同樣。注:須要在web.xml中註冊

  • FilterChain類型於棧。Filter在調用FilterChain的doFilter()方法以前攔截請求,以後攔截響應。
  • 若是直接給Servlet傳遞ServletResponse對象,Servlet響應會直接返回給客戶端,不會通過Filter。因此若是要攔截響應,則須要FilterChain的doFilter()方法傳遞HttpServletResponseWrapper對象,最後響應纔會進過Filter。其中:HttpServletWrapper使用了裝飾器設計模式。
 1 @WebFilter(urlPatterns = "/*")
 2 public class EncodeFilter implements Filter {
 3     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
 4     request.setCharacterEncoding("UTF-8");
 5     chain.doFilter(request, response);
 6     }
 7     public void destroy() {
 8     }
 9     public void init(FilterConfig arg0) throws ServletException {
10     }
11 }
相關文章
相關標籤/搜索