Java基礎知識問答

談談servlet的生命週期
1)容器裝載並實例化Servlet 
2) 調用init()方法完成Servlet初始化 
3)當請求到達時,調用service()方法處理請求,產生響應 
4)銷燬階段調用destroy()方法完成清理工作。 
servlet是線程安全的嗎?爲什麼? 
不安全。因爲Servlet對象在整個過程中,至始至終只有一個對象。以節約服務器資源的消耗,這就意味着很多個線程會同時訪問一個Servlet對象。所以線程不安全。 
你是如何處理servlet線程安全問題的? 
解決Servlet線程安全問題方法有三種 
1)編寫Servlet類的時候,實現SingleThreadModel接口,將Servlet變成單線程機制。 
2)涉及對共享資源訪問的時候,使用synchronized同步加鎖,實現共享資源的保護。 
3)儘量不在Servlet中定義成員變量,使用局部變量。 
三種方法中,最好使用第三種,這樣線程安全,並且性能最高。 
如何得到客戶端的請求參數
request.getParameter()單個數據 
request.getParameterValues()一組數據 
request.getParameterMap()返回所有的鍵值對 
request.getParameter和request.getParameterValues的區別,它們的返回值是什麼類型? 
     request.getParameter獲得單個表單的數據。返回值是String類型。而request.getParameterValues()是獲得表單元素名相同的一組數據。返回值是String[]數組。 
jsp有哪些內置對象? 
pageContex,request,session,application,out,exception,config,page, 
請求轉發和重定向的區別。 
1) 內部轉發客戶端向服務器發起一次請求,重定向客戶端向服務器發出兩次請求 
2) 內部轉發由request對象發起,重定向是response發起的 
3) 內部轉發不會引起地址欄的變化,而重定向會導致地址欄變化 
JSP中動態包含和靜態包含的區別。 
1) 靜態包含在轉換成爲java文件的時候將要包含的文件包含進來,作爲一個整體編譯。動態包含是各個包含文件分別轉換,分別編譯。 
2) 靜態包含在兩個文件中不能有相同的變量,動態包含允許 
3) 靜態包含只能包含文件,動態包含還可以包含servlet輸出的結果 
4) 靜態包含不能使用變量作爲文件名,動態包含可以使用變量作爲文件名 
5) 動態包含文件發生變化,包含文件會感知變化。 


一、Servlet是什麼?JSP是什麼?它們的聯繫與區別是什麼?
ServletJava編寫的運行在Servlet容器的服務端程序,狹義的Servlet是指Servlet接口,廣義的Servlet是指任何實現Servlet接口的類,我們一般理解的爲後者。Servlet的作用是接收瀏覽器發給服務器的請求Request,經過處理後,將返回響應Response給瀏覽器。
JSP是一種後端腳本語言,是爲了解決Html是靜態的,而Servlet輸出動態頁面又太複雜的問題而出現的,通過JSP標籤、動作、內置對象提供方便的生成動態網頁功能,是一種後端渲染技術。

聯繫和區別:
1、JSP其實就是基於Servlet實現的,JSP生命週期
     (1)解析階段:Servlet容器解析JSP代碼,如果有錯則報錯;
     (2)翻譯階段:Servlet容器翻譯JSP代碼爲Servlet源文件;
     (3)編譯階段:Servlet容器編譯Servlet源代碼,生成Servlet字節碼類文件;
       ……剩下就是Servlet的生命週期,會在下面介紹。
2、JSP注重視圖顯示、Servlet注重控制,在傳統的MVC架構中,JSP是View,Servlet是Controller。
3、JSP在修改靜態內容時不需要重新編譯。

二、Servlet API
核心包:javax.servlet與javax.servlet.http
核心類\接口:
1、javax.servlet.Servlet:Servlet核心接口,定義了init()、service()、destroy()有關Servlet 生命週期的方法。
2、javax.servlet.ServletConfig:Servlet配置接口,定義了getServletContext(),主要用於獲取ServletContext實例。
3、javax.servlet.ServletContex:Servlet上下文接口,相當於Web應用的總管家。定義了getAtrribute(String name)、setAttribute(String name, Object object)、getInitParameter(String name)、getContextPath()、getRequestDispatcher(String path)等方法,主要用於應用間通信,獲取web應用資源、訪問服務器文件資源、輸出日誌等功能。
4、javax.servlet.GenericServlet:該包下唯一抽象類,實現了ServletConfig、Servlet接口,爲兩個接口方法提供默認的實現方式。


三、如何使用Servlet
1、繼承GenericServlet類(通用)
(1)GenericServlet類有一個關鍵的設計,定義了一個私有的ServletConfig成員變量,在init()方法中,由Servlet容器傳入ServletConfig對象與之匹配。
(2)GenericServlet類中唯一一個抽象方法是Service方法,子類必須實現Service方法,以爲用戶提供特定的服務。

2、繼承HttpServlet類,是GenericServlet的子類,重寫了Service方法,提供了HTTP的相關服務實現。用戶需要做的事,根據實際情況,重寫doPost()、doGet()等方法。

四、Servlet生命週期
1、初始化階段
(1)將編譯後的servlet字節碼文件讀入內存;
(2)Servlet容器創建ServletConfig,並與ServletContext對象建立關聯關係,即調用ServletConfig的getServletContext()方法會獲取到ServletContext對象。
(3)創建Servlet對象。
(4)調用GenericServlet的init(ServletConfig config)方法,建立Servlet對象與ServletConfig對象的關聯。
初始化時機:
(1)未配置<load-on-startup>屬性的Servlet被客戶端首次訪問時纔會被初始化。
(2)配置<load-on-startup>屬性的Servlet在web容器啓動時就會按配置的數值按順序被初始化。

2、運行時階段,調用Servlet類的Service()方法。當Servlet將響應返回後,Servlet容器會銷燬HttpServletRequest對象與HttpServletResponse對象。

3、銷燬階段,在web容器終止時,會先調用所有Servlet的destroy()方法。

五、ServletContextListener監視器
通過實現ServletContextListener接口,實現contextInitialized(ServletContextEvent sce)與contextDestroyed(ServletContextEvent sce)方法,其中可以通過參數的getServletCotext()方法獲取ServletContext對象以完成監聽工作。

注意:Servlet、Listener、Filter三者的加載順序爲:Listener>Filter>Servlet

六、請求轉發與重定向特點以及它們的區別
1、請求轉發:HttpServletRequest.getRequestDispatcher(String path).forward(request, response);
特點:
(1)服務器內部轉發,瀏覽器URL不會改變,對用戶透明。整體體現的是一個請求與一個響應。
(2)請求轉發前,會清空響應緩衝區。
(3)如果轉發的爲Servlet或JSP(JSP也是Servlet),就會直接將當前HttpServletRequest對象與HttpServletResponse對象轉交給目標Servlet或JSP的Service方法,處理後將響應結果返回給前端。
(4)如果轉發的爲Html靜態文檔,則就讀取文檔中數據發送到前端。
(5)請求轉發不會執行轉發方法之後的代碼
2、重定向:HttpServletResponse.sendRedirect(String path);
特點:
(1)客戶端外部轉發,瀏覽器URL會發生改變。在Servlet調用重定向後,會返回302臨時重定向狀態碼,響應內容爲待重定向路徑。然後,瀏覽器就會再次發出請求,請求路徑爲剛剛相應內容中的路徑。整體體現的是兩個請求與兩個響應。
(2)重定向前,也會清空響應緩衝區。
(3)而重定向會執行重定向方法後的代碼

區別彙總:
1、請求轉發在服務端完成,重定向在客戶端完成。
2、請求轉發速度快,重定向速度慢。
3、請求轉發是一次請求,一次響應;而重定向是兩次請求,兩次響應。
4、請求轉發不會執行轉發方法之後的代碼;而重定向會執行重定向方法後的代碼。
5、請求轉發URL不會發生改變;而重定向URL會發生改變。
6、請求轉發必須在同一臺服務器下完成;而重定向可以在不同服務器下完成。

注意:請求轉發與重定向的資源路徑表示是有區別的
請求轉發的path一般使用"/資源名",這裏的 '/' 就代表了項目根路徑 "http://localhost:8080/項目名/";
而重定向的path一般使用context.getContextPath() + "/資源名",不能直接使用"/資源名",因爲在重定向中"/"代表了Web站點的根路徑"http://localhost:8080"。

七、如何訪問Servlet容器中的其他Web應用
在Service中編寫如下代碼:
ServletContext otherContext = context.getContext("/otherApp");
otherContext.getRequestDispatcher("/資源名").forward(request, response);

八、如何保證Servlet線程安全
1、保證變量作用域合理,線程私有的變量要定義在方法中。
2、共享變量要用保證線程安全,可以使用加鎖、atomic類、volatile關鍵字實現。

九、JSP九大內置對象(詳情可參看博客http://blog.csdn.net/zhangliangzi/article/details/49965209
1、request對象——代表javax.servlet.http.HttpServletRequest對象
2、response對象——代表javax.servlet.http.HttpServletResponse對象
3、session對象——代表javax.servlet.http.HttpSession對象
4、application對象——代表javax.servlet.ServletContext對象
5、pageContext對象——代表javax.servlet.jsp.pageContext對象
6、page對象——代表this
7、config對象——代表javax.servlet.ServletConfig對象
8、out對象——代表javax.servlet.jsp.jspWriter對象
9、exception對象——代表java.lang.Exception對象

十、Session與Cookie
爲什麼要使用Session與Cookie:Web應用一般使用HTTP協議傳輸數據,HTTP是一種無狀態協議,完成數據交換後客戶端與服務端的連接就會關閉。所以服務端無法根據HTTP請求區分請求者。但區分請求者身份是是非常有意義的,比如一個購物車系統,添加一件商品到購物車,服務端必須區分是哪個用戶添加的商品;而且如果一段時間內某個用戶多次發出請求,那麼就可以對用戶的相關數據進行緩存,提高訪問效率。這都可以通過Session與Cookie實現。

Cookie與Session的區別在於:Cookie存在於客戶端,Session存在於服務端。Cookie的存儲數量是有限制的,安全性也更差。Session是基於Cookie實現的,但服務端爲了獲得較高的存取速度,會把Session放到內存中,在高併發環境下會增大服務器壓力。

Cookie機制:
Cookie基於瀏覽器的支持,具有“不可跨域名性”,瀏覽器只能訪問當前域名網站的Cookie。
Cookie的常見屬性有如下幾個:
String name——Cookie的名稱,一旦創建便不能更改;
Object value——Cookie的值;
int maxAge——Cookie失效時間,單位爲秒;
boolean secure——Cookie是否使用HTTPS或SSL的安全數據,傳輸前要加密,默認爲false
String domain——Cookie的作用域名,比如設置爲".google.com",第一個字符必須爲點,代表着以google.com爲結尾的域名纔可以訪問該Cookie。
String path——Cookie的作用項目名,比如設置爲"/webApp/",最後一個字符必須爲斜線,代表着contextPath爲"/webApp"的程序纔可以訪問該Cookie。
Cookie使用:
Cookie cookie = new Cookie("name","StringValue"); // 新建Cookie
Cookie[] cookies = request.getCookie(); //獲取客戶端提交的所有cookie
cookie.setDomain(".leeon.top"); //設置作用域名
cookie.setPath("/testApp/"); //設置作用項目路徑
cookie.setSecure(true); //設置安全屬性
cookie.setMaxAge(Integer.MAX_VALUE); // 設置生命週期爲永久;
response.addCookie(cookie); // 輸出到客戶端
在網頁URL欄輸入:javascript:alert (document. cookie) 可輸出當前頁面cookie
注意:
Coookie不能修改與刪除,修改可通過創建同名Cookie後覆蓋原Coolkie;刪除可通過設置setMaxAge方法中的參數爲0。
setMaxAge方法中的參如果設置爲負值,則爲存放在內存中的臨時Cookie,關閉瀏覽器即失效;如果設置爲0,則代表使Cookie失效。

Session會話機制:
Session基於Cookie的工作流程:
(1)當用戶通過瀏覽器進程第一次請求一個支持會話的資源時,Servlet容器會爲這個會話創建一個HttpSession對象,併爲其分配一個唯一的ID,當前會話就此開始。
(2)把這個唯一的ID以name爲JSESSIONID的Cookie形式添加到響應中,返回給客戶端保存。(當Cookie被禁用時,使用URL重寫機制,在URL後添加;jsessionid=XXX以傳輸HttpSession對象標識)
(3)當瀏覽器進程再次請求這個支持會話的資源時,會在請求頭中加上一直保持着的JSESSIONID,Servlet容器會在HTTP請求頭中自動查找這個Cookie(也可以通過HttpSession.getId()方法主動獲取),如果找到,就取出對應HttpSession對象(其實用戶第一次訪問,也會進行相同的查詢,因爲查詢不到,纔會執行創建操作)。
Session使用:
HttpSession session = request.getSession(); //獲取Session對象
session.setAtrribute("name", "StringValue");//加入session
session.getAttribute("name");//獲取session
session.removeAtrribute("name");//刪除session
session.setMaxInactiveInterval(int second);//設置超時時間,單位爲秒,默認20分鐘
session.getLastAccessedTime();//返回Session的最後活躍時間
Session持久化:
1、StandarManager是默認的Session Manager(用來管理Session)。它的實現機制是:當Tomcat服務器關閉或重啓,或Web應用被重新加載時,會將內存中所有的HttpSession對象保存到文件系統中,默認的文件路徑是:%CATALINA_HOME%\work\Catalina\<applicaton-name>\SESSIONS.ser
重啓Tomcat後,Tomcat服務器把SESSIONS.ser中的持久化HttpSession對象加載到內存中。
2、PersistentManager能夠把HttpSession對象保存到Session Store中,它提供了比較StandarManager更靈活的管理功能,具有容錯能力,控制內存中HttpSession對象的數目等。
Tomcat實現Session Store的接口爲org.apache.catalina.session.Store,目前提供了兩個實現這一接口的類:org.apache.catalina.session.FileStore和org.apache.catalina.session.JDBCStore。FileStore會將HttpSession對象保存到文件系統中;而JDBCStore則將HttpSession對象保存到數據庫表中。
發佈了9 篇原創文章 · 獲贊 17 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章