一、什么是Servlet?
Servlet 是在服務器上運行來響應客戶端請求的一種java組件。Servlet與具體的客戶服務端協議無關,但Servlet常用于HTTP協議,所以,“Servle”t常被用于“HTTP Servlet”的意思。
Servlet使用的java軟件包:javax.servlet(基本Servlet框架)和javax,servlet.http(HTTP Servlet)
HTTP Servlets典型應用包括:
1.通過提交HTML表單操作存儲數據。
2.提供動態內容,如將從數據庫中查詢到的結果返回給客戶端
3.管理無狀態的HTTP上的有狀態的信息,如一個為多個同時存在的客戶管理購物車并映射每一個請求到正確的客戶的在線購物系統
二、Servlets 和 CGI(Commone Gateway Interface)
最早用來產生動態網頁服務的方法便是CGI,CGI是一種與語言無關的接口,此種接口允許服務器啟動通過環境變化來獲取與此次請求有關信息的外部程序。每一個請求都通過CGI程序或者CGI腳本由單獨的線程響應。
Servlets相比CGI的幾個優勢:
1.Servlet中,每個請求由一個輕量級的Java線程處理,不用為每一個請求啟動新的系統線程。
2.一個Servlet在請求期間會駐留在內存中。
3.響應所有并發的請求只需要唯一一個實例,節省了內存并可以使Servlet管理持久數據顯得更快捷。
三、Servlet 生命周期
Servlet 的生命周期就是指創建 Servlet 實例之后其存在的時間以及何時消失
生命周期的 3個方法為:init()、service()、destroy()
1.裝載servlet類以及其他可能使用到的類
2.調用init(ServletConfig config)方法加載配置信息,初始化servlet
3.調用service(doGet/doPost)方法處理業務邏輯,service方法在初始化前不會被調用
4.調用destroy方法銷毀不再使用的servlet
四、Servlet的部署
1.用myeclipse建立好web工程,寫好HelloClientServlet.java類
1
import java.io.*;
2
import javax.servlet.*;
3
import javax.servlet.http.*;
4
5
public class HelloClientServlet extends HttpServlet
6

{
7
//doGet() 方法處理客戶端作出的 GET 請求。
8
public void doGet(HttpServletRequest req,
9
HttpServletResponse res)
10
throws ServletException, IOException
11
{
12
res.setContentType("text/html");
13
PrintWriter out = res.getWriter();
14
out.println("<HTML><HEAD><TITLE>Hello Client!</TITLE>"+
15
"</HEAD><BODY>Hello Client!</BODY></HTML>");
16
out.close();
17
}
18
19
//doPost() 方法處理客戶端作出的 POST 請求。
20
public void doPost(HttpServletRequest req,
21
HttpServletResponse res)
22
throws ServletException, IOException
23
{
24
doGet(req,res);
25
}
26
}
2.web.xml文件中配置Servlet
1
<!-- 第一個servlet程序配置 -->
2
<servlet>
3
<servlet-name>firstServlet</servlet-name>
4
<servlet-class>HelloClientServlet的包路徑</servlet-class>
5
</servlet>
6
<!-- 第一個servlet程序映射 -->
7
<servlet-mapping>
8
<servlet-name>firstServlet</servlet-name><!-- 必須與配置中的servlet-name相同 -->
9
<url-pattern>/first.do</url-pattern>
10
</servlet-mapping>
3.發布到本機web服務器(使用Tomcat5.5)中,通過http://localhost:服務器端口號/工程名/first.do啟動servlet。
五、javax.servlet 包的接口介紹
ServletConfig
用來封裝web.xml中對當前Servlet的配置信息
getInitParameter()---可以獲取初始化參數
ServletContext
代表當前Servlet運行的上下文環境,Web容器會為每一個Web工程創建一個對應ServletContext對象
setAttribute()
getAttribute()
removeAttribute()
ServletRequest
為Servlet所發送的請求,用ServletRequest封裝
setAttribute()
getAttribute()
removeAttribute()
getParameter()
常用子接口HttpServletRequest
ServletResponse
Servlet對客戶段所做的響應,用ServletResponse描述
getWriter():獲取PrintWriter輸出流給客戶發送的響應內容
setContentType:設置響應內容的響應類型和字符集信息
sendRedirect:設置重新請求路徑
子接口HttpServletResponse
六、過濾器(Filter)
1.Servlet 過濾器是小型的 Web 組件,它們攔截請求和響應,以便查看、提取或以某種方式操作正在客戶機和服務器之間交換的數據。
2.生命周期
初始化----當容器第一次加載該過濾器時, init() 方法將被調用。
過濾----doFilter() 方法被容器調用,同時傳入分別指向這個請求/響應鏈中的ServletRequest 、 ServletResponse 和 FilterChain 對象的引用
銷毀----容器緊跟在垃圾收集之前調用 destroy() 方法
3.編寫字符編碼過濾器
(1)實現Filter接口中的三個方法:
init() ----這個方法在容器實例化過濾器時被調用
doFilter() ----與 servlet 擁有一個 service() 方法(這個方法又調用 doPost() 或者 doGet() )來處理請求一樣,過濾器擁有單個用于處理請求和響應的方法―― doFilter()。
destroy() ---這個方法執行任何清理操作,這些操作可能需要在自動垃圾收集之前進行
1
import java.io.IOException;
2
3
import javax.servlet.Filter;
4
import javax.servlet.FilterChain;
5
import javax.servlet.FilterConfig;
6
import javax.servlet.ServletException;
7
import javax.servlet.ServletRequest;
8
import javax.servlet.ServletResponse;
9
10
public class CharacterEncodingFilter implements Filter
11

{
12
13
private String encode;
14
15
public void destroy()
16
{
17
this.encode = null;
18
}
19
20
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
21
throws IOException, ServletException
22
{
23
if(encode!=null)
24
{
25
request.setCharacterEncoding(encode);
26
response.setCharacterEncoding(encode);
27
}
28
// 將資源鏈到下一Filter, 如果這是最后一個Filter, 則將資源鏈到目的位置.
29
chain.doFilter(request, response);
30
}
31
32
public void init(FilterConfig config) throws ServletException
33
{
34
encode = config.getInitParameter("encode");
35
System.out.println("CharacterEncoding
encode="+encode);
36
}
37
38
}
(2)web.xml文件中配置字符編碼過濾器
1
<!-- 字符編碼過濾器配置 -->
2
<filter>
3
<filter-name>encodeFilter</filter-name>
4
<filter-class>CharacterEncodingFilter全路徑</filter-class>
5
<init-param>
6
<param-name>encode</param-name>
7
<param-value>utf-8</param-value>
8
</init-param>
9
</filter>
10
<!-- 字符編碼過濾器映射,/*過濾所有請求 -->
11
<filter-mapping>
12
<filter-name>encodeFilter</filter-name>
13
<url-pattern>/*</url-pattern>
14
</filter-mapping>
七、監聽器(ServletContextListener)
1.ServletContext相關監聽接口
(1)javax.servlet.ServletContextListener:監聽WEB應用,當應用開始的時候它會調用contextInitialized()方法,當應用關閉的時候,它同樣會調用contextDestroyed()方法
(2)javax.servlet.ServletContextAttributeListener:用于監聽WEB應用屬性改變的事件,包括:增加屬性、刪除屬性、修改屬性
2.HttpSession相關監聽接口
(1)javax.servlet.http.HttpSessionListener:監聽HttpSession的操作。當創建一個Session時,激發session Created(HttpSessionEvent se)方法;當銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se)方法。
(2)avax.servlet.http.HttpSessionBindingListener:
注意:HttpSessionBindingListener接口是唯一不需要再web.xml中設定的Listener
當我們的類實現了HttpSessionBindingListener接口后,只要對象加入Session范圍(即調用HttpSession對象的setAttribute方法的時候)或從Session范圍中移出(即調用HttpSession對象的removeAttribute方法的時候或Session Time out的時候)時,容器分別會自動調用下列兩個方法:
void valueBound(HttpSessionBindingEvent event)
void valueUnbound(HttpSessionBindingEvent event)
(3)avax.servlet.http.HttpSessionAttributeListener:監聽HttpSession中的屬性的操作。
當在Session增加一個屬性時,激發attributeAdded(HttpSessionBindingEvent se) 方法;當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEvent se)方法;當在Session屬性被重新設置時,激發attributeReplaced(HttpSessionBindingEvent se) 方法。
3.寫一個統計在線用戶的例子
(1)建立CunterListstener.java類
1
import javax.servlet.http.HttpSessionEvent;
2
import javax.servlet.http.HttpSessionListener;
3
4
public class CunterListstener implements HttpSessionListener
5

{
6
public static int count;
7
8
public void sessionCreated(HttpSessionEvent arg0)
9
{
10
count++;
11
}
12
13
public void sessionDestroyed(HttpSessionEvent arg0)
14
{
15
if(count>0) count--;
16
}
17
}
(2)建立index.jsp,查看在線人數
1
<%
@ page language="java" pageEncoding="UTF-8"%>
2
<html>
3
<head>
4
<title>站點計數監聽器</title>
5
</head>
6
7
<body>
8
<h1>站點計數監聽器</h1>
9
<hr>
10
當前在線人數:<%=CunterListener.count%>
11
</body>
12
</html>
3.在web.xml文件中配置監聽器
1
<!-- 配置監聽器 -->
2
<listener>
3
<listener-class>CunterListstener全路徑</listener-class>
4
</listener>
4.發布工程到Tomcat上,進入index.jsp網頁 ,看到網頁內容: 當前在線人數:1。代表的是只有自己在線。
九、Cookie
Cookie 用于存儲 Web 服務器發送給客戶端的信息。服務器通過設置響應標題中的 Set-Cookie 方法來發送 cookie。
javax.servlet.http.Cookie類方法:
getComment/setComment 獲取/設置Cookie的注釋。
getDomain/setDomain 獲取/設置Cookie適用的域。
getMaxAge/setMaxAge 獲取/設置Cookie過期之前的時間,以秒計。
getName/setName 獲取/設置Cookie的名字。
getPath/setPath 獲取/設置Cookie適用的路徑。
getSecure/setSecure 獲取/設置一個boolean值,表示是否Cookie只能通過加密的連接(即SSL)發送。
getValue/setValue 獲取/設置Cookie的值。
getPath()返回的如果不指定路徑,Cookie將返回給當前頁面所在目錄及其子目錄下的所有頁面。這里的方法可以用來設定一些更一般的條件。例如,someCookie.setPath("/"),此時服務器上的所有頁面都可以接收到該Cookie。
如果不設置Cookie的過期時間,則Cookie只在當前會話內有效,即在用戶關閉瀏覽器之前有效,而且這些Cookie不會保存到磁盤上。
通過HttpServletResponse的addCookie方法加入。
1
Cookie userCookie = new Cookie("userName", "hackiller");
2
response.addCookie(userCookie);
由于HttpServletRequest的getCookies方法返回的是一個Cookie對象的數組,因此通常要用循環來訪問這個數組查找特定名字,然后用getValue檢查它的值。
1
//獲取指定名字的Cookie值
2
public static String getCookieValue(Cookie[] cookies,String cookieName,String defaultValue)
3

{
4
for(int i=0; i<cookies.length; i++)
5
{
6
Cookie cookie = cookies[i];
7
if (cookieName.equals(cookie.getName())) return(cookie.getValue());
8
}
9
return(defaultValue);
10
}
自動保存的Cookie,Cookie能夠在瀏覽器退出的時候自動保存下來
1
import javax.servlet.http.Cookie;
2
3
public class MyCookie extends Cookie
4

{
5
public static final int COOKIE_MAX_AGE = 60*60*24*7;//一周
6
public MyCookie(String cookieName, String cookieValue)
7
{
8
super(cookieName, cookieValue);
9
//設置Cookie的過期時間為一周
10
setMaxAge(COOKIE_MAX_AGE);
11
}
12
}
十、Servlet 通信方法
(1)Servlet 使用 RequestDispatcher 接口的 forward() 和include() 方法訪問網絡資源
將請求從一個 Servlet 轉送到同一個服務器上的另一個 Servlet
public void forward (ServletRequest req, ServletResponse res);
在一個 Servlet 中包含另一個 Servlet 的內容
public void include (ServletRequest req, ServletResponse res);
使用javax.servlet.http.HttpServlet.getServletContext()方法創建RequestDispatcher對象,用于訪問另一個 Servlet 的內容
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("/usersServlet2");
(2)Servlet 上下文
將所有 Servlet 所共有的屬性和資源存儲于 ServletContext 接口對象。處理上下文屬性的方法為:
public Object getAttribute(String name);
返回 Servlet 容器屬性名稱。如果該名稱沒有屬性則返回 null
public void setAttribute(String name, Object object);
將對象綁定到 Servlet 上下文中給定的屬性名稱
public void removeAttribute(String name);
刪除給定名稱的屬性