1. 程式人生 > 其它 >java常見面試題:javaWeb

java常見面試題:javaWeb

Java 常見面試題

Java Web

jsp 和 servlet 有什麼區別?

jsp經編譯後就變成了Servlet.(JSP的本質就是Servlet,JVM只能識別java的類,不能識別JSP的程式碼,Web容器將JSP的程式碼編譯成JVM能夠識別的java類)
jsp更擅長表現於頁面顯示,servlet更擅長於邏輯控制。
Servlet中沒有內建物件,Jsp中的內建物件都是必須通過HttpServletRequest物件,HttpServletResponse物件以及HttpServlet物件得到。
Jsp是Servlet的一種簡化,使用Jsp只需要完成程式設計師需要輸出到客戶端的內容,Jsp中的Java指令碼如何鑲嵌到一個類中,由Jsp容器完成。而Servlet則是個完整的Java類,這個類的Service方法用於生成對客戶端的響應。

jsp 有哪些內建物件?作用分別是什麼?

JSP有9個內建物件:
request:封裝客戶端的請求,其中包含來自GET或POST請求的引數;
response:封裝伺服器對客戶端的響應;
pageContext:通過該物件可以獲取其他物件;
session:封裝使用者會話的物件;
application:封裝伺服器執行環境的物件;
out:輸出伺服器響應的輸出流物件;
config:Web應用的配置物件;
page:JSP頁面本身(相當於Java程式中的this);
exception:封裝頁面丟擲異常的物件。

說一下 jsp 的 4 種作用域?

JSP中的四種作用域包括page、request、session和application,具體來說:
page代表與一個頁面相關的物件和屬性。
request代表與Web客戶機發出的一個請求相關的物件和屬性。一個請求可能跨越多個頁面,涉及多個Web元件;需要在頁面顯示的臨時資料可以置於此作用域。
session代表與某個使用者與伺服器建立的一次會話相關的物件和屬性。跟某個使用者相關的資料應該放在使用者自己的session中。
application代表與整個Web應用程式相關的物件和屬性,它實質上是跨越整個Web應用程式,包括多個頁面、請求和會話的一個全域性作用域。

由於HTTP協議是無狀態的協議,所以服務端需要記錄使用者的狀態時,就需要用某種機制來識具體的使用者,這個機制就是Session.典型的場景比如購物車,當你點選下單按鈕時,由於HTTP協議無狀態,所以並不知道是哪個使用者操作的,所以服務端要為特定的使用者建立了特定的Session,用用於標識這個使用者,並且跟蹤使用者,這樣才知道購物車裡面有幾本書。這個Session是儲存在服務端的,有一個唯一標識。在服務端儲存Session的方法很多,記憶體、資料庫、檔案都有。叢集的時候也要考慮Session的轉移,在大型的網站,一般會有專門的Session伺服器叢集,用來儲存使用者會話,這個時候 Session 資訊都是放在記憶體的,使用一些快取服務比如Memcached之類的來放 Session。
思考一下服務端如何識別特定的客戶?這個時候Cookie就登場了。每次HTTP請求的時候,客戶端都會發送相應的Cookie資訊到服務端。實際上大多數的應用都是用 Cookie 來實現Session跟蹤的,第一次建立Session的時候,服務端會在HTTP協議中告訴客戶端,需要在 Cookie 裡面記錄一個Session ID,以後每次請求把這個會話ID傳送到伺服器,我就知道你是誰了。有人問,如果客戶端的瀏覽器禁用了 Cookie 怎麼辦?一般這種情況下,會使用一種叫做URL重寫的技術來進行會話跟蹤,即每次HTTP互動,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的引數,服務端據此來識別使用者。
Cookie其實還可以用在一些方便使用者的場景下,設想你某次登陸過一個網站,下次登入的時候不想再次輸入賬號了,怎麼辦?這個資訊可以寫到Cookie裡面,訪問網站的時候,網站頁面的指令碼可以讀取這個資訊,就自動幫你把使用者名稱給填了,能夠方便一下使用者。這也是Cookie名稱的由來,給使用者的一點甜頭。所以,總結一下:Session是在服務端儲存的一個數據結構,用來跟蹤使用者的狀態,這個資料可以儲存在叢集、資料庫、檔案中;Cookie是客戶端儲存使用者資訊的一種機制,用來記錄使用者的一些資訊,也是實現Session的一種方式。

說一下 session 的工作原理?

其實session是一個存在伺服器上的類似於一個散列表格的檔案。裡面存有我們需要的資訊,在我們需要用的時候可以從裡面取出來。類似於一個大號的map吧,裡面的鍵儲存的是使用者的sessionid,使用者向伺服器傳送請求的時候會帶上這個sessionid。這時就可以從中取出對應的值了。

Cookie與 Session,一般認為是兩個獨立的東西,Session採用的是在伺服器端保持狀態的方案,而Cookie採用的是在客戶端保持狀態的方案。但為什麼禁用Cookie就不能得到Session呢?因為Session是用Session ID來確定當前對話所對應的伺服器Session,而Session ID是通過Cookie來傳遞的,禁用Cookie相當於失去了Session ID,也就得不到Session了。
假定使用者關閉Cookie的情況下使用Session,其實現途徑有以下幾種:
設定php.ini配置檔案中的“session.use_trans_sid = 1”,或者編譯時開啟打開了“--enable-trans-sid”選項,讓PHP自動跨頁傳遞Session ID。
手動通過URL傳值、隱藏表單傳遞Session ID。
用檔案、資料庫等形式儲存Session ID,在跨頁過程中手動呼叫。

spring mvc 和 struts 的區別是什麼?

  1. 攔截機制的不同
    Struts2是類級別的攔截,每次請求就會建立一個Action,和Spring整合時Struts2的ActionBean注入作用域是原型模式prototype,然後通過setter,getter吧request資料注入到屬性。Struts2中,一個Action對應一個request,response上下文,在接收引數時,可以通過屬性接收,這說明屬性引數是讓多個方法共享的。Struts2中Action的一個方法可以對應一個url,而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法了,只能設計為多例。
    SpringMVC是方法級別的攔截,一個方法對應一個Request上下文,所以方法直接基本上是獨立的,獨享request,response資料。而每個方法同時又何一個url對應,引數的傳遞是直接注入到方法中的,是方法所獨有的。處理結果通過ModeMap返回給框架。在Spring整合時,SpringMVC的Controller Bean預設單例模式Singleton,所以預設對所有的請求,只會建立一個Controller,有應為沒有共享的屬性,所以是執行緒安全的,如果要改變預設的作用域,需要新增@Scope註解修改。
    Struts2有自己的攔截Interceptor機制,SpringMVC這是用的是獨立的Aop方式,這樣導致Struts2的配置檔案量還是比SpringMVC大。
  2. 底層框架的不同
    Struts2採用Filter(StrutsPrepareAndExecuteFilter)實現,SpringMVC(DispatcherServlet)則採用Servlet實現。Filter在容器啟動之後即初始化;服務停止以後墜毀,晚於Servlet。Servlet在是在呼叫時初始化,先於Filter呼叫,服務停止後銷燬。
  3. 效能方面
    Struts2是類級別的攔截,每次請求對應例項一個新的Action,需要載入所有的屬性值注入,SpringMVC實現了零配置,由於SpringMVC基於方法的攔截,有載入一次單例模式bean注入。所以,SpringMVC開發效率和效能高於Struts2。
  4. 配置方面
    spring MVC和Spring是無縫的。從這個專案的管理和安全上也比Struts2高。

如何避免 sql 注入?

PreparedStatement(簡單又有效的方法)
使用正則表示式過濾傳入的引數
字串過濾
JSP中呼叫該函式檢查是否包函非法字元
JSP頁面判斷程式碼

什麼是 XSS 攻擊,如何避免?

XSS攻擊又稱CSS,全稱Cross Site Script (跨站指令碼攻擊),其原理是攻擊者向有XSS漏洞的網站中輸入惡意的 HTML 程式碼,當用戶瀏覽該網站時,這段 HTML 程式碼會自動執行,從而達到攻擊的目的。XSS 攻擊類似於 SQL 注入攻擊,SQL注入攻擊中以SQL語句作為使用者輸入,從而達到查詢/修改/刪除資料的目的,而在xss攻擊中,通過插入惡意指令碼,實現對使用者遊覽器的控制,獲取使用者的一些資訊。 XSS是 Web 程式中常見的漏洞,XSS 屬於被動式且用於客戶端的攻擊方式。
XSS防範的總體思路是:對輸入(和URL引數)進行過濾,對輸出進行編碼。

什麼是 CSRF 攻擊,如何避免?

CSRF(Cross-site request forgery)也被稱為 one-click attack或者 session riding,中文全稱是叫跨站請求偽造。一般來說,攻擊者通過偽造使用者的瀏覽器的請求,向訪問一個使用者自己曾經認證訪問過的網站傳送出去,使目標網站接收並誤以為是使用者的真實操作而去執行命令。常用於盜取賬號、轉賬、傳送虛假訊息等。攻擊者利用網站對請求的驗證漏洞而實現這樣的攻擊行為,網站能夠確認請求來源於使用者的瀏覽器,卻不能驗證請求是否源於使用者的真實意願下的操作行為。
如何避免:

  1. 驗證 HTTP Referer 欄位
    HTTP頭中的Referer欄位記錄了該 HTTP 請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求來自於同一個網站,而如果黑客要對其實施 CSRF
    攻擊,他一般只能在他自己的網站構造請求。因此,可以通過驗證Referer值來防禦CSRF 攻擊。
  2. 使用驗證碼
    關鍵操作頁面加上驗證碼,後臺收到請求後通過判斷驗證碼可以防禦CSRF。但這種方法對使用者不太友好。
  3. 在請求地址中新增token並驗證
    CSRF 攻擊之所以能夠成功,是因為黑客可以完全偽造使用者的請求,該請求中所有的使用者驗證資訊都是存在於cookie中,因此黑客可以在不知道這些驗證資訊的情況下直接利用使用者自己的cookie 來通過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能偽造的資訊,並且該資訊不存在於 cookie 之中。可以在 HTTP 請求中以引數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有token或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。這種方法要比檢查 Referer 要安全一些,token 可以在使用者登陸後產生並放於session之中,然後在每次請求時把token 從 session 中拿出,與請求中的 token 進行比對,但這種方法的難點在於如何把 token 以引數的形式加入請求。
    對於 GET 請求,token 將附在請求地址之後,這樣 URL 就變成 http://url?csrftoken=tokenvalue。
    而對於 POST 請求來說,要在 form 的最後加上 <input type="hidden" name="csrftoken" value="tokenvalue"/>,這樣就把token以引數的形式加入請求了。
  4. 在HTTP 頭中自定義屬性並驗證
    這種方法也是使用 token 並進行驗證,和上一種方法不同的是,這裡並不是把 token 以引數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裡。通過 XMLHttpRequest 這個類,可以一次性給所有該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的位址列,也不用擔心 token 會透過 Referer 洩露到其他網站中去。