我的servlet學習過程(三):Servlet

一、servlet入門程序:

Hello servlet.java

package cn.study;

import java.io.*;

import javax.servlet.*;

public class FirstServlet extends GenericServlet{

public void service(ServletRequest req,ServletResponse res)

    throws ServletException,java.io.IOException

      {

         String data = "hello servlet!!";

         OutputStream out = res.getOutputStream();

         out.write(data.getBytes());

        }

}

web.xml 文件:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    version="2.5">

    <servlet>

        <servlet-name>FirstServlet</servlet-name>

        <servlet-class>cn.itcast.FirstServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>FirstServlet</servlet-name>

        <url-pattern>/xxx</url-pattern>

    </servlet-mapping>

</web-app>

之後放進服務器發佈訪問即可

二、servlet調用過程:


1.Servlet的一些細節:

a)客戶端是通過URL地址訪問web服務器中的資源,所以Servlet程序若想被外界訪問,必須把servlet程序映射到一個URL地址上,這個工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成;<servlet>元素用於註冊Servlet,它包含有兩個主要的子元素:<servlet-name><servlet-class>,分別用於設置Servlet的註冊名稱和Servlet的完整類名;一個<servlet-mapping>元素用於映射一個已註冊的Servlet的一個對外訪問路徑,它包含有兩個子元素:<servlet-name><url-pattern>,分別用於指定Servlet的註冊名稱和Servlet的對外訪問路徑


b)同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的 <servlet-name>子元素的設置值可以是同一個Servlet的註冊名;在Servlet映射到的 URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴展名”, 另一種格式是以正斜槓“/”開頭並以“/*”結尾


c 看哪個servlet格式相近則優先調用


d)servlet是一個供其他Java程序(Servlet引擎)調用的Java類,它不能獨立運行,它的運行完全由Servlet引擎來控制和調度;針對客戶端的多次Servlet請求,通常情況下,服務器只會創建一個Servlet實例對象,也就是說Servlet實例對象一旦創建,它就會駐留在內存中,爲後續的其它請求服務,直至web容器退出,servlet實例對象纔會銷燬;在Servlet的整個生命週期內,Servletinit方法只被調用一次。而對一個Servlet的每次訪問請求都導致Servlet引擎調用一次servletservice方法。對於每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然後將這兩個對象作爲參數傳遞給它調用的Servletservice()方法,service方法再根據請求方式分別調用doXXX方法

e)如果在<servlet>元素中配置了一個<load-on-startup>元素,那麼WEB應用程序在啓動時,就會裝載並創建Servlet的實例對象、以及調用Servlet實例對象的init()方法

用途:爲web應用寫一個InitServlet,這個servlet配置爲啓動時裝載,爲整個web應用創建必要的數據庫表和數據


f)如果某個Servlet的映射路徑僅僅爲一個正斜槓(/),那麼這個Servlet就成爲當前Web應用程序的缺省Servlet;凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它們的訪問請求都將交給缺省Servlet處理,也就是說,缺省Servlet用於處理所有其他Servlet都不處理的訪問請求;在<tomcat的安裝目錄>\conf\web.xml文件中,註冊了一個名稱爲org.apache.catalina.servlets.DefaultServletServlet,並將這個Servlet設置爲了缺省Servlet;當訪問Tomcat服務器中的某個靜態HTML文件和圖片時,實際上是在訪問這個缺省Servlet

g)線程安全:當多個客戶端併發訪問同一個Servlet時,web服務器會爲每一個客戶端的訪問請求創建一個線程,並在這個線程上調用Servletservice方法,因此service方法內如果訪問了同一個資源的話,就有可能引發線程安全問題。

如果某個Servlet實現了SingleThreadModel接口,那麼Servlet引擎將以單線程模式來調用其service方法;SingleThreadModel接口中沒有定義任何方法,只要在Servlet類的定義中增加實現SingleThreadModel接口的聲明即可;對於實現了SingleThreadModel接口的ServletServlet引擎仍然支持對該Servlet的多線程併發訪問,其採用的方式是產生多個Servlet實例對象,併發的每個線程分別調用一個獨立的Servlet實例對象;實現SingleThreadModel接口並不能真正解決Servlet的線程安全問題,因爲Servlet引擎會創建多個Servlet實例對象,而真正意義上解決多線程安全問題是指一個Servlet實例對象被多個線程同時調用的問題。事實上,在Servlet API 2.4中,已經將SingleThreadModel標記爲Deprecated(過時的)

2.ServletConfig對象:

servlet的配置文件中,可以使用一個或多個<init-param>標籤爲servlet配置一些 初始化參數;當servlet配置了初始化參數後,web容器在創建servlet實例對象時, 會自動將這些初始化參數封裝到ServletConfig對象中,並在調用servletinit 法時,將ServletConfig對象傳遞給servlet。進而,程序員通過ServletConfig對象 就可以得到當前servlet的初始化參數信息

SercletContext對象:

ServletContext對象代表當前的web應用,可以使用ServletConfig.getServletContext() 獲取ServletContext對象,一個web應用中的所有servlet共享一個ServletContext 對象

應用:

a)多個Servlet通過ServletContext對象實現數據共享

b)獲取WEB應用的初始化參數,在web.xml使用<context-param>標籤可配置 ServletContext的初始化參數

c)實現Servlet的轉發

實現方法:ServletContext context = this.getServletContext();

ServletContext context = servletConfig.getServletContext();

   RequestDispatcher rd = context.getRequestDispatcher(“/xxx/XXX”);

 rd.forward(request,response);

d)利用ServletContext對象讀取資源文件的三種方法

a)第一種方法


b)第二種方法


c)第三種方法


PS:做web工程時不建議採用傳統的FileInputStream方式讀取資源文件

  另外一種讀取資源文件的方式:用類加載器

 

PS:讀取的資源文件不宜過大,容易造成jvm內存溢出

Request 與 Response

Response

3.常見應用:

a)向客戶端輸出數據(OutputStreamPrintWriter

OutputStream

response.setHeader(“content-type”,”text/html;charset=UTF-8”);

response.getOutputStream().writer(“XXXX”.getBytes(“UTF-8”));

PrintWriter

response.setHeader(“content-type”,”text/html;charset=UTF-8”);

response.getWriter().writer(“XXXX”);

輸出中文的問題,防止中文亂碼,可以

//設置response使用編碼表,控制response用何種編碼表向瀏覽器輸 入數據,默認爲ISO-8859-1

response.setCharacterEncoding(“UTF-8”);

//指定瀏覽器以什麼編碼表打開服務器發送的數據

response.setHeader(“Content-type”,”text/html;charset=UTF-8”);

或直接 response.setContentType(“text/html;charset=UTF-8”)

b)文件下載


若下載文件名爲中文,則需要變動一處地方

response.setHeader(“content-disposition”,”attachment;filename=”+URLEnco der.encode(filename,"UTF-8"));

c)生成隨機圖片


js實現點擊圖片更換

<img src=”xxxx”  οnclick=”changeImage(this)”  alt=”換一張” />

function changeImage(img){

img.src = img.src+”?”+new Date().getTime();

}

d)控制瀏覽器定時刷新頁面


e)控制瀏覽器禁止緩存當前內容


f)實現請求重定向:

實現原理:302狀態碼+location響應頭

特點:瀏覽器會向服務器發送2次請求,瀏覽器地址欄發生變化,創2request/response

response.setStatus(302);

response.setHeader("location", "/index.jsp");

或者response.sendRedirect("/index.jsp");

四、Response細節:

getOutputStreamgetWriter方法分別用於得到輸出二進制數據、輸出文 本數據的ServletOuputStreamPrintwriter對象;getOutputStream getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再 調用另一方法; 

Servlet程序向ServletOutputStreamPrintWriter對象中寫入的數據將被 Servlet 引擎從response裏面獲取,Servlet引擎將這些數據當作響應消 息的正文,然後再與響應狀態行和各響應頭組合後輸出到客戶端; Serlvetservice方法結束後,Servlet引擎將檢查getWriter getOutputStream 方法返回的輸出流對 象是否已經調用過close方法, 如果沒有,Servlet引擎將 調用close方法關 閉該輸出流對象

<meta>標籤控制瀏覽器行爲:

<meta http-equiv=’消息頭’  content=’’內容 >

五、Request

常用方法:

request請求參數亂碼:

//對於post請求,只對post有效

request.setCharacterEncoding("UTF-8");

//對於get請求,只能手工處理

data = new String(data.getBytes("iso-8859-1"),"UTF-8");

request實現請求與轉發:

特點:客戶端只發一次請求,而服務器有多個web資源被調用,客戶端 瀏覽地址沒有發生變化,整個過程只有1request/response

request.getRequestDispatcher(“/index.jsp”).forward(request,response);

六、細節:

forward方法用於將請求轉發到RequestDispatcher對象封裝的資源;如果 在調用forward方法之前,在Servlet程序中寫入的部分內容已經被真 正 地傳送到了客戶端(如:輸出流被關閉或者轉發已完成等等)forward 法將拋出IllegalStateException異常;如果在調用forward方法之前向 Servlet引擎的緩衝區中寫入了內容,只要寫入到緩衝區中的內容還沒有 被真正輸出到客戶端,forward方法就可以被正常執行,原來寫入到輸 出緩衝區中的內容將被清空,但是,已寫入到HttpServletResponse對象中 的響應頭字段信息保持有效

requestDispatcher對象的include方法實現頁面包含:


Web工程中各類地址的寫法原則:

一般以 開頭,若是給服務器用 / 代表當前應用,給瀏覽器用 / 代表 網站,網站下有多個應用

使用request防盜鏈:

使用request.getHeader(“referer”),判斷獲取的referer是否爲空或者不是以 自己網站開頭,是的話則跳轉到網站首頁,不是的話則展示內容

七、CookieSession

1.Cookie

Cookie是客戶端技術,程序把每個用戶的數據以cookie的形式寫給用戶各 自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着 各自的數據去。這樣,web資源處理的就是用戶各自的數據了

2.Session

Session是服務器端技術,利用這個技術,服務器在運行時可以爲每一個用 戶的瀏覽器創建一個其獨享的session對象,由於session爲用戶瀏覽器獨享, 所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session 中,當用戶再去訪問服務器中的其它web資源時,其它web資源再從用戶各 自的session中取出數據爲用戶服務

3.Cookie技術圖解:


4.Session技術圖解:


5.Cookie的細節:

一個Cookie只能標識一種信息,它至少含有一個標識該信息的名稱(NAME 和設置值(VALUE;一個WEB站點可以給一個WEB瀏覽器發送多個Cookie 一個WEB瀏覽器也可以存儲多個WEB站點提供的Cookie;瀏覽器一般只允 許存放300Cookie,每個站點最多存放20Cookie,每個Cookie的大小 限制爲4KB;如果創建了一個cookie,並將他發送到瀏覽器,默認情況下它是 一個會話級別的cookie(即存儲在瀏覽器的內存中),用戶退出瀏覽器之後即 被刪除。若希望瀏覽器將該cookie存儲在磁盤上,則需要使用maxAge,並給 出一個以秒爲單位的時間。將最大時效設爲0則是命令瀏覽器刪除該cookie; 注意,刪除cookie時,path必須一致,否則不會刪除

6.Session的細節:

WEB開發中,服務器可以爲每個用戶瀏覽器創建一個會話對象(session 象),注意:一個瀏覽器獨佔一個session對象(默認情況下);因此,在需 要 保存用戶數據時,服務器程序可以把用戶數據寫到用戶瀏覽器獨佔的session 中,當用戶使用瀏覽器訪問其它程序時,其它程序可以從用戶的session中取 出該用戶的數據,爲用戶服務

Session是基於Cookie創建的,因爲服務器爲每個瀏覽器創建一個session完成的 時候,每個session都有一個id,服務器會使用cookie將這個id帶回去給瀏覽器, 以告訴瀏覽器自己所對應的session

7.瀏覽器禁用cookie後的session處理:

解決方案:URL重寫

response. encodeRedirectURL(java.lang.String url) 

//用於對sendRedirect方法後的url地址進行重寫

response. encodeURL(java.lang.String url)

//用於對錶單action和超鏈接的url地址進行重寫

8.防止表單重複提交:

表單頁面由servlet程序生成,servlet爲每次產生的表單頁面分配一個唯一的 隨機標識號,並在FORM表單的一個隱藏字段中設置這個標識號,同時在當 前用戶的Session域中保存這個標識號;當用戶提交FORM表單時,負責處理 表單提交的serlvet得到表單提交的標識 號,並與session中存儲的標識號比 較,如果相同則處理表單提交,處理完後清除當前用戶的Session域中存儲的 標識號

在下列情況下,服務器程序將拒絕用戶提交的表單請求:

a.存儲Session域中的表單標識號與表單提交的標識號不同

b.當前用戶的Session中不存在表單標識號

c.用戶提交的表單數據中沒有標識號字段

標識類的編寫:


八、requestcookiesessionservletContext四大域對象的使用場景: 

request:當程序產生的數據一顯示完以後就沒用了,就使用request

session:當程序產生的數據顯示完之後的短時間內還要用,就使用session

cookie:當程序產生的數據顯示完之後,在較長時間內還要,使用cookie

servletContext:當程序產生的數據顯示完之後還要用,而且還需要與別的程序 共享(如聊天室等等),就使用servletContext

九、sessioncookie

1、服務器是如何做到一個session爲一個瀏覽器的多次請求而服務

1.1  服務器創建session出來後,會把 sessionid號,以cookie的形式回寫給客戶機,這樣,只要客戶機的瀏覽器不關,再去訪問服務器時,都會帶着session id號去,服務器發現客戶機帶session id過來了,就會使用內存中與之對應的session爲之服務

2、如何做到一個session爲多個瀏覽器服務

2.1  服務器第一次創建session,程序員把session id號,手工以cookie的形式回送給瀏覽器,並設置cookie的有效期,這樣,即使用戶的瀏覽器關了,開新瀏覽器時,還會帶着session id找服務器,服務器從而就可以用內存中與之對應的session爲第二個瀏覽器窗口服務

3、如何做用戶禁用cookie後,session還能爲多次請求而服務

3.1  把用戶可能點的每一個超鏈接後面,都跟上用戶的session id

4session對象的創建和銷燬時機

4.1 用戶第一次request.getSession

4.2 session對象默認30分鐘沒有使用,則服務器會自動銷燬session,

4.2.1  用戶在web.xml文件中手工配置session的失效時間



servlet部分的總結就到這裏了,主要是對servlet的一些配置、request、response、cookie、session相關技術的簡單介紹,是servlet學習必須要熟悉的東西,基礎中的基礎,需要好好掌握,而且面試有時也會被問到,第三部分就到這裏~~~~~

發佈了32 篇原創文章 · 獲贊 10 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章