剛學習完了Servlet相關的知識,如今作一下整理以備往後方便查找與複習.
一.Servlet的定義
Servlet是一個位於服務器端的獨立於平臺和協議的Java應用程序,能夠生成動態的web頁面,也能夠像jsp同樣直接輸出信息.
Servlet類是一個繼承了HttpServlet類的Java類,可是有本身的規則.Servlet是位於Web服務器內部的服務器端的Java應用程序,像全部的Java程序同樣,Servlet擁有面向對象Java語言的全部優點
Servlet必須在web.xml文件中註冊.服務器啓動的時候,能夠根據這些配置來加載Servlet類.
二.Servlet的做用:
Servlet主要用來在控制層結合mvc模式作控制轉發.
Servlet的應用:
表單是HTML中使用最普遍的傳遞信息的手段,Servlet使用HttpServlet類中的方法與表單進行交互,HTTPServer把客戶請求正確的映射到相應的函數上:
a) doGet 用於處理GET請求,也能夠自動的支持HEADER請求
b) doPost 用於處理POST請求
三.Servlet的生命週期
Servlet繼承了HTTPServlet類,因此要擴展父類中的方法:
1.init()方法:
在 Servlet 的生命期中,僅執行一次init方法.它是在服務器裝入 Servlet 時執行的.
例:
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occure
* 在servlet被第一次訪問時,本方法將會被自動調用
* 本方法被稱爲初始化方法
* 只會被調用一次
*/
public void init() throws ServletException {
// Put your code here
System.out.println("我是init方法");
}
2.service()方法:
service方法是Servlet的核心.每當一個客戶請求一個HttpServlet對象,該對象的service()方法就要被調用,doGet和doPost這兩個方法是由service方法調用的
例:
/**
* 具體的業務方法
* 該方法將會被調用屢次
* 每次訪問servlet時,該方法都會被調用
* service根據request.getMethod獲得你的提交方式,而後由它來決定對doGet.doPost的調用
*/
public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
super.service(request, response);
System.out.println("我是service.....................................");
}
3.destroy()方法
destroy()方法僅執行一次,即在服務器中止且卸裝Servlet時執行該方法.
例:
/**
* Destruction of the servlet. <br>
* servlet被註銷的時候
* 本方法爲銷燬方法
* 也只是被服務器自動調用一次
*
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
System.out.println("destroy方法被調用..............");
}
四.Servlet定義的步驟
1.定義一個類,繼承HTTPServlet類.
2.重寫doGet和doPost方法.
3.實現doGet和doPost的邏輯.
4.在web.xml部署描述文件中定義Servlet的映射方式.
五.Servlet在web.xml中的配置
1.配置說明
<servlet>內的<servlet-name>,是一個邏輯名,能夠是任何有效的標識名;
<init-param>是Servlet初始參數在Servlet的init()方法中經過getInitParameter(「ip」)取得,返回String型數據;
<servlet- mapping>內的<servlet-name>與<servlet>內的<servlet-name>一一對應,把客戶端對/HelloServlet的請求對應到<servlet- class>project1.HelloServlet</servlet-class>所指定的位置;
<url-pattern>/HelloServlet</url-pattern>指在IE url中的請求形式.這裏的/是相對於當前的web目錄的.
例:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>project1.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
2.歡迎頁面的設置:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
若是第一個頁面找不到,會依次向下找
3.errorpage的配置:
<error-page>
<error-code>404</error-code>
<location>/notFileFound.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/null.html</location>
</error-page>
4.爲Servlet定義初始化參數
使用getInitParameter()方法來提取servlet的初始化參數
定義以下:
<servlet>
<servlet-name>a</servlet-name>
<servlet-class>jsj.lx.demo.MyServlet</servlet-class>
<init-param>
<param-name>type</param-name>
<param-value>text/html;charset=GBK</param-value>
</init-param>
</servlet>
提取方式:
String str = this.getInitParameter("type");
六.用Servlet控制會話
Servlet定義了一個HTTPsession接口,實現session的功能.在訪問者從某個特定的主頁到離開爲止的那段時間,每一個訪問者都會單獨得到一個session.
使用HTTPServletRequest的getSession方法獲得當前存在的session,若是當前沒有定義session,則建立一個新的session.
當用完session後,可使用session.invalidate()方法關閉session.可是這並非嚴格要求的.由於,Servlet引擎在一段時間以後會自動關閉session.還能夠在web.xml中配置session的過時時間,單位是分鐘:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
例:
(1)
HttpSession session = request.getSession();
session.setAttribute("username", "scott");
RequestDispatcher rd = request.getRequestDispatcher("A.jsp");
rd.forward(request, response);
(2)
HttpSession ss = request.getSession();
List list=new ArrayList();
list.add("SMITH");
list.add("ALLEN");
ss.setAttribute("userlist", list);
七.Filter過濾器
1.定義:ServletFilter是Servlet2.3規範中新增長的,它是截取用戶從客戶端提交的請求,在尚未到達須要訪問的資源時欲行的一個類.它的操縱來自客戶端的請求,在資源尚未發送到客戶端前截取響應,並處理這些尚未發送到客戶端的響應.
2.ServletFilter的做用:
權限的校驗,日誌記錄,圖片的轉換,數據的加密等等.
3.實現:一個ServletFilter能夠分爲兩部分:Java類自身以及在web.xml文件中xml.
要做爲 ServletFilter的Java類必須實現Filter接口.該接口由一對自描述的生命週期方法 init(FilterConfig),destroy()和一個行爲方法doFilter(ServletRequest, ServletResponse, FilterChain).
4.實現步驟:
a.實現Filter接口
b.實現doFilter方法
c.傳遞過濾鏈,放請求經過
d.在web.xml文件中註冊過濾器
八.監聽器Listener
1.定義:Listioner是Servlet的監聽器,它能夠監聽客戶端的請求,服務取得操做等.
經過監聽器,能夠自動激發一些操做,好比監聽在先的用戶的數量.當增長一個HTTPsession時,就激發sessionCreated(HTTPsessionEvent sec)方法,這樣就能夠進行頁面訪問統計了.
2.經常使用監聽接口:
a) ServletContextAttributeListenner監聽對ServletContext屬性的操做,好比增長,刪除,修改屬性.
b) ServletContextListener監聽ServletContext.
當建立ServletContext時,激發contextInitialized(ServletContextEvent sce)方法.
當銷燬ServletContext時,激發contextDestroyed(ServletContextEvent sce)方法.
c) HttpSessionListener監聽HttpSession的操做
當建立一個Session時,激發sessionCreated(HttpSessionEvent se)方法;
當銷燬一個Session時,激發sessionDestroyed(HttpSessionEvent se)方法.
d) HttpSessionAttributeListener監聽HttpSession中的屬性的操做
當在Session增長一個屬性時,激發attributeAdded(HttpSessionBindingEvent se) 方法;
當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEvent se)方法;
當在Session屬性被從新設置時,激發attributeReplaced(HttpSessionBindingEvent se)方法.
Listener的配置:
<listener>
<listener-class>OnLineCountListener</listener-class>
</listener>
九.字符的中文轉換問題
中文轉換能夠分多種狀況:
1.若是頁面中使用jsp:include或jsp:forward關係,中文字符集轉換用:
request.setCharacterEncoding("GBK");
2.在Servlet中顯示中文:
因爲沒法使用jsp頁面中的編碼指令
<%@ page language="java" import="java.util.*" contentType="text/html;charset=GBK"%>
那麼在Servlet中設置輸出編碼就應該經過:
response.setContentType("text/html;charset=GBK");
3.普通的參數傳遞
普通的參數也須要考慮到中文的問題.除了頁面顯示設置contentType="text/html;charset=GBK"以外,咱們還須要對中文字符進行字符轉換硬編碼:
超連接:
String str = request.getParameter("username");
str = new String(str.getBytes("iso8859-1"),"GBK");
form表單:
String str= request.getParameter("username");
str = new String(str.getBytes("iso8859-1"),"GBK");
javascript轉向:
String str = request.getParameter("username");
str = new String(str.getBytes("ISO8859-1"),"gbk");
response方式轉向:
String message = "個人中文測試";
response.sendRedirect("L.jsp?message="+URLEncoder.encode(message));
接收頁面:
String message = request.getParameter("message");
message = new String(message.getBytes("ISO8859-1"),"GBK");
request等做用域不須要進行轉換,只要在頁面顯示設置中設置就能夠了
request.setAttribute("username","個人測試名稱");
session.setAttribute("passwd","個人密碼");
十.Servlet線程
Servlet體系結構是創建在java多線程機制之上的,它的生命週期是由web容器負責的.當客戶端第一次請求某個Servlet時,Servlet容器將會根據web.xml配置文件實例化這個Servlet類.當有新的客戶端請求該Servlet時,通常不會再實例化該Servlet類,也就是有多個線程在使用這個實例.Servlet容器會自動使用線程池等技術來支持系統的運行.
例:
boolean shutdown = true;
/**
* 線程體
*/
public void run(){
int i = 0;
while(true){
i++;
System.out.println(Thread.currentThread().getName()+"="+i);
if(shutdown == false){
break;
}
}
System.out.println("本線程結束!");
}
java線程共享數據的概念:
多線程使用的數據是共享的,Servlet自己創建在多線程的基礎上,因此對於全局變量也存在"共享數據"的問題.
在Servlet中定義一個全局變量,該數據將會被多個線程"共享"
例:
String username;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
username = request.getParameter("username");
try{
Thread.sleep(1000*6);
}catch(InterruptedException e){
e.printStackTrace();
}
out.println(username);
out.close();
}
對於上面這個例子,若是同時提交兩個請求:
http://loclhost:8088/servlet/MyServlet?username=zhangsanfeng
http://loclhost:8088/servlet/MyServlet?username=zhangwuji
則兩個結果都將顯示爲zhangwuji.
這是由於第一個在訪問時,獲得了zhangsanfeng的值,後來username的值被賦爲zhangwuji.又由於username是被多個線程所共享的,因此全部裏面的username都變成了zhangwuji.爲了不這樣的錯誤,最好避免使用全局變量而使用臨時變量.由於方法中的臨時變量時在棧上分配空間,並且每一個線程都有本身私有的棧空間,因此他們不會影響線程的安全.
十一.自動加載Servlet
Servlet有一個生命週期方法,init,service,destroy.其中init在 Servlet第一次訪問的時候訪問,它只能被訪問一次.而若是你須要在服務器啓動的時候讓Servlet自動啓動,你能夠經過load-on- startup來實現.load-on-startup是web.xml文件中Servlet的配置節點.
舉例: 若是想要在服務器啓動時從數據庫中查詢全部的用戶名列表,以便在其餘頁面中能夠直接使用,而不須要從數據庫在進行查詢,如何實現? 1.ServletContentListener能夠再服務器啓動時自動執行其方法 2.可使用一個Servlet,而後定義load-on-startup,讓它可以在服務器啓動時自動執行其方法.使用<load-on-startup>1</load-on-startup>能夠指定服務器加載順序. 代碼以下: /** * Initialization of the servlet. <br> * * @throws ServletException if an error occure * 本方法在servlet被加載時訪問 * 這裏,咱們在服務器啓動,自動加載一段數據,起到數據緩存的效果 */ public void init() throws ServletException { // Put your code here List<String> list = new ArrayList<String>(); list.add("WARD"); list.add("JONES"); list.add("JAMES"); this.getServletContext().setAttribute("datalist",list); } 配置文件設置: <servlet> <servlet-name>DataCacheServlet</servlet-name> <servlet-class>com.sun.demo.DataCacheServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>