一、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調用過程:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zM4gTM1kTNwIjNxgDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
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的整個生命周期内,Servlet的init方法隻被調用一次。而對一個Servlet的每次通路請求都導緻Servlet引擎調用一次servlet的service方法。對于每次通路請求,Servlet引擎都會建立一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然後将這兩個對象作為參數傳遞給它調用的Servlet的service()方法,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.DefaultServlet的Servlet,并将這個Servlet設定為了預設Servlet;當通路Tomcat伺服器中的某個靜态HTML檔案和圖檔時,實際上是在通路這個預設Servlet
g)線程安全:當多個用戶端并發通路同一個Servlet時,web伺服器會為每一個用戶端的通路請求建立一個線程,并在這個線程上調用Servlet的service方法,是以service方法内如果通路了同一個資源的話,就有可能引發線程安全問題。
如果某個Servlet實作了SingleThreadModel接口,那麼Servlet引擎将以單線程模式來調用其service方法;SingleThreadModel接口中沒有定義任何方法,隻要在Servlet類的定義中增加實作SingleThreadModel接口的聲明即可;對于實作了SingleThreadModel接口的Servlet,Servlet引擎仍然支援對該Servlet的多線程并發通路,其采用的方式是産生多個Servlet執行個體對象,并發的每個線程分别調用一個獨立的Servlet執行個體對象;實作SingleThreadModel接口并不能真正解決Servlet的線程安全問題,因為Servlet引擎會建立多個Servlet執行個體對象,而真正意義上解決多線程安全問題是指一個Servlet執行個體對象被多個線程同時調用的問題。事實上,在Servlet API 2.4中,已經将SingleThreadModel标記為Deprecated(過時的)
2.ServletConfig對象:
在servlet的配置檔案中,可以使用一個或多個<init-param>标簽為servlet配置一些 初始化參數;當servlet配置了初始化參數後,web容器在建立servlet執行個體對象時, 會自動将這些初始化參數封裝到ServletConfig對象中,并在調用servlet的init方 法時,将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)向用戶端輸出資料(OutputStream與PrintWriter)
用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次請求,浏覽器位址欄發生變化,創 建2對request/response
response.setStatus(302);
response.setHeader("location", "/index.jsp");
或者response.sendRedirect("/index.jsp");
四、Response細節:
getOutputStream和getWriter方法分别用于得到輸出二進制資料、輸出文 本資料的ServletOuputStream、Printwriter對象;getOutputStream和 getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再 調用另一方法;
Servlet程式向ServletOutputStream或PrintWriter對象中寫入的資料将被 Servlet 引擎從response裡面擷取,Servlet引擎将這些資料當作響應消 息的正文,然後再與響應狀态行和各響應頭組合後輸出到用戶端; Serlvet的service方法結束後,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資源被調用,用戶端 浏覽位址沒有發生變化,整個過程隻有1對request/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是否為空或者不是以 自己網站開頭,是的話則跳轉到網站首頁,不是的話則展示内容
七、Cookie與Session:
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;浏覽器一般隻允 許存放300個Cookie,每個站點最多存放20個Cookie,每個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.使用者送出的表單資料中沒有辨別号字段
辨別類的編寫:
八、request、cookie、session與servletContext四大域對象的使用場景:
request:當程式産生的資料一顯示完以後就沒用了,就使用request
session:當程式産生的資料顯示完之後的短時間内還要用,就使用session
cookie:當程式産生的資料顯示完之後,在較長時間内還要,使用cookie
servletContext:當程式産生的資料顯示完之後還要用,而且還需要與别的程式 共享(如聊天室等等),就使用servletContext
九、session與cookie:
1、伺服器是如何做到一個session為一個浏覽器的多次請求而服務
1.1 伺服器建立session出來後,會把 session的id号,以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号
4、session對象的建立和銷毀時機
4.1 使用者第一次request.getSession時
4.2 session對象預設30分鐘沒有使用,則伺服器會自動銷毀session,
4.2.1 使用者在web.xml檔案中手工配置session的失效時間
servlet部分的總結就到這裡了,主要是對servlet的一些配置、request、response、cookie、session相關技術的簡單介紹,是servlet學習必須要熟悉的東西,基礎中的基礎,需要好好掌握,而且面試有時也會被問到,第三部分就到這裡~~~~~