1. 程式人生 > >Servlet學習應該注意的幾點

Servlet學習應該注意的幾點

一、Servlet生命週期(即執行過程)

(1)初始階段,呼叫init()方法

(2)響應客戶請求階段,呼叫service()方法。由service()方法根據提交方式不同執行doGet()或doPost()方法,其中service()方法判斷了到底執行doGet()還是doPost()方法。

(3)終止階段,呼叫destroy()方法。(伺服器關閉)

Servlet生命週期中需要注意一下幾點:

1)Servlet是長期貯存記憶體中的,當Servlet例項載入後,Servlet物件是長期儲存在伺服器記憶體中的

2)Servlet被裝載後,Web容器建立一個Servlet例項並且呼叫Servlet的init()方法進行初始化。在Servlet的整個生命週期內,init()方法只被呼叫一次。而service()方法在每次客戶端請求的時候都會呼叫。

3)HttpServlet中有兩個Service()方法,HttpServlet中兩個service()方法的區別:

複製程式碼
  public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.service(arg0, arg1);
    }
  protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws
ServletException, IOException { // TODO Auto-generated method stub super.service(arg0, arg1); }
複製程式碼

A:其中第一種方法是由tomcat自動呼叫,它將接收的客戶端請求轉交給HttpServlet中的第二個service()方法,此保護類行的service()方法再把請求分發給doPost()、doGet()方法進行下一步處理。

B:HttpServlet類繼承自GenericServlet,HttpServletRequest和HttpServletResponse分別繼承自ServletRequest,ServletResponse,簡單說,就是第一個方法是HttpServlet的,第二個方法是GenericServlet的,HttpServlet因為繼承GenericServlet,所以繼承了這個service()方法。

二、Servlet與九大內建物件

Servlet中如何獲取JSP的九大內建物件

JSP物件 怎樣獲得 作用域
out response.getWriter() page
request service方法中的request引數 request
response service方法中的response引數 response
session request.getSession()函式 session
application this.getServletContext()函式 Application
exception new Throwable() page
page this page
pageContext new pageContext() page
config this.getSerletConfig()函式 page

將這九大物件分為

1、out物件和session物件

out物件是通過service()中的response的getWriter()方法獲得,而response.getWriter()的返回的是PrintWriter類物件,而out物件是JspWriter類的例項,我們不妨對比一下兩個類的方法。不難發現兩個類都主要以print()方法為主。

session物件是通過service()中的request的getSession()方法獲得,返回的物件就是對應了session例項。

程式碼示例(以out物件舉例):

index.jsp程式碼

複製程式碼
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
    <a href="Servlets/ServletDemo1"><h1>測試servletDemo1 servlet</h1></a>
  </body>
</html>
複製程式碼

servletDemo1.java程式碼

複製程式碼
package Servlets;

import java.io.IOException;
import java.io.PrintWriter;import javax.el.ELContext;
import javax.servlet.Servlet;import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspWriter;public class ServletDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //resp.setHeader("Content-type", "text/html;charset=gbk");
        //resp.setCharacterEncoding("gbk");

        System.out.println("測試ServletDemo1 doGet方法成功!");
        PrintWriter out=resp.getWriter();
        StringBuffer bf=new StringBuffer("<h1>這裡是ServletDemo1 servlet!</h1>");
        out.print(bf);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }    
}
複製程式碼

執行結果截圖:

分析:綠色背景的程式碼實現了在servlet中獲取out物件,並進行相應操作。但是我們發現通過out物件列印輸出的漢字出現了亂碼。

關於Servlet中的printWriter中文亂碼的問題:

先分析原因:首先我們應該瞭解servlet中的兩個引數request和response分別用來儲存客戶端傳送的請求、儲存伺服器端返回的資料,而不管是儲存還是取出都涉及到重新編碼解析的問題,在這個過程如果儲存和取出時使用的編碼方式不同,勢必會導致亂碼。printWriter物件是通過response引數呼叫getWriter()函式獲得的,作為響應的資訊會在響應儲存的時候進行編碼的相關操作,而sun公司使用的碼錶是ISO8859-1之類的碼錶,而當瀏覽器顯示響應結果時,也會去查碼錶,而中文的windows下的瀏覽器使用的一般是gbk或者gb2312,這樣兩次編碼就不同。

解決方法:(兩種)

(1)doxxx()方法中新增:response.setCharacterEncoding("gbk");

(2)doxxx()方法中新增:response.setHeader("content-type","text/html;charset=gbk");

上面程式碼中藍色部分就是解決方法示例:

執行之後的結果截圖:

當然,通過request的getSession()方法獲得的session物件對於中文字元也可能出現亂碼的問題,我們也可以通過新增:request.setCharaterEncoding("utf-8/gbk");

2、request物件和response物件

request和response物件都是通過service()方法傳進的引數獲得的,並且這兩個引數直接被傳入doGet()和doPost()的引數中。

複製程式碼
  public void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.service(arg0, arg1);
    }

複製程式碼
@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

3、page物件、config物件和application物件

page物件代表了JSP轉譯的servlet例項物件,而在繼承HttpServlet類的自定義Servlet類中,其當前例項物件在類中的表達,很明顯使用this。所以page物件對應this完美。

config物件其實是通過自定義Servlet類的getSerletConfig()方法獲取,自定義Servlet類繼承自HttpServlet類,而getServletConfig()方法是HttpServlet類繼承自其父類GenericServlet類而來,返回型別為ServletConfig對應了config的類。既然是呼叫其自定義Servlet類本身的getServletConfig()方法,則呼叫的寫法應該是:this.getServletConfig();

application物件其實是通過自定義Servlet類的getSerletcontext()方法獲取,自定義Servlet類繼承自HttpServlet類,而getServletContext()方法是HttpServlet類繼承自其父類GenericServlet類而來,返回型別為ServletContext對應了application的類。既然是呼叫其自定義Servlet類本身的getSerletcontext()方法,則呼叫的寫法應該是:this.getSerletcontext()。

 程式碼演示:

複製程式碼
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
  <%
  application.setAttribute("name", "小帥哥");
   %>
    <a href="Servlets/ServletDemo1"><h1>測試servletDemo1 servlet</h1></a>
  </body>
</html>
複製程式碼 複製程式碼
package Servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.Enumeration;

import javax.el.ELContext;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.VariableResolver;

public class ServletDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("content-type", "text/html;charset=gbk");
        ServletConfig sc=this.getServletConfig();
        Enumeration e=sc.getInitParameterNames();
       ServletContext application= this.getServletContext();
       String name=(String)application.getAttribute("name");
        PrintWriter out=resp.getWriter();
        out.print("<h2>name:"+name+"</h2>");
        out.print("<h1>初始化的引數名:</h1>");
        if(e.hasMoreElements()){
            out.print(e.nextElement()+" ");
        }else{
            out.print("該Servlet沒有初始化引數!");
        }
        //req.getRequestDispatcher("/index1.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }    
}
複製程式碼

執行結果截圖:

4、pageContext物件和exception物件

pageContex是通過在Servlet中通過構造起自己構造的,構造的方法是:PageContext pc=new pageContext(),但是pageContext類是抽象類,通過直接new的方式可以獲得pageContext物件,但是其中的方法需要覆蓋重寫才有意義,而重寫的,裡面的方法的實現大多都需要藉助於其他內建物件,pageContext是一個集大成者的內建物件,他的出現就是能實現,一個內建物件能夠訪問其他內建物件。

複製程式碼
PageContext pc=new PageContext() {
        
        @Override
        public void setAttribute(String arg0, Object arg1, int arg2) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void setAttribute(String arg0, Object arg1) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void removeAttribute(String arg0, int arg1) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void removeAttribute(String arg0) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public VariableResolver getVariableResolver() {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public JspWriter getOut() {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public ExpressionEvaluator getExpressionEvaluator() {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public ELContext getELContext() {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public int getAttributesScope(String arg0) {
            // TODO Auto-generated method stub
            return 0;
        }
        
        @Override
        public Enumeration<String> getAttributeNamesInScope(int arg0) {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public Object getAttribute(String arg0, int arg1) {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public Object getAttribute(String arg0) {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        public Object findAttribute(String arg0) {
            // TODO Auto-generated method stub
            return null;
        }
        
        @Override
        
            
           

相關推薦

Servlet學習應該注意

一、Servlet生命週期(即執行過程) (1)初始階段,呼叫init()方法 (2)響應客戶請求階段,呼叫service()方法。由service()方法根據提交方式不同執行doGet()或doPost()方法,其中service()方法判斷了到底執行doGet()

用phpqrcode生成帶logo二維碼, 需注意,不注意是要進坑的哦.

先附上程式碼: include '../vendor/phpqrcode/phpqrcode.php'; $value = 'http://127.0.0.1/txw1958/'; //二維碼內容 $errorCorrectionLevel = 'L';//容錯級別

心理壓力大胃腸容易變弱 注意可緩解

現如今的都市生活中競爭十分的激烈,這樣就往往使職場的白領心理壓力很大。然而,心理壓力大是會影響到各個方面的,一定要及時的減壓才行。在這裡,就來教教大家如何減壓,千萬別錯過了。 心理壓力大危害多 影響大腦。法國研究人員發現一種酶,一旦受到壓力就會攻擊大腦海馬區負責調節神經突觸的分子,使

Android Studio初次使用genymotion注意

至於怎麼下載安裝設定genymotion等等內容不在贅述,一搜一大把 初次使用genymotion注意以下幾點: 1.genymotion Setting-ADB中設定Android SDK路徑與Android Studio路徑一致。 genymotion 預設不會設定的

【自省】學習程式設計的經驗教訓

1. 講究效率,切勿把筆記變手賬   可以記筆記,但只需記重點,莫要把筆記程式設計手掌。掌握學習內容後不會翻詳細美麗筆記的,搜尋引擎就夠了。筆記起到鞏固記憶的作用就行了。 2. 選擇合適的教程,感覺沒有收穫就及時換教程   不要相信大眾推薦的優質教程,發現不合適

CC2530 2.4G ZigBee 低功耗PCB設計需注意

該PCB採用四層層疊結構,頂層為訊號層,布有2.4G天線鏈路,形成了微帶線。第二層為地層,由於該電路是模數混合,地層進行了內層分割,通過0歐電阻連線。第三層是電源層,通過電池供電,經過LDO穩壓晶片輸出VDD_3.3v給數位電路供電,輸出VCC_3.3v給類比電路供電,類比

整合LeanCloud使用者反饋SDK要注意

1.在 Xcode 中選擇 UniversalFramework Target,裝置選為 iOS Device,在 Product 選單中選擇 Archive 即可開始編譯。編譯完成之後會在當前 build 目錄下。 注意,不能直接點Run按鈕,直接點Run按

設計快取系統時應該注意問題

前言設計一個快取系統,不得不要考慮的問題就是:快取穿透、快取擊穿與失效時的雪崩效應。快取穿透快取穿透是指查詢一個一定不存在的資料,由於快取是不命中時被動寫的,並且出於容錯考慮,如果從儲存層查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到儲存層去查詢,失去了快取的

python的學習注意初學的個例子

第一天學習的總結: 1.瞭解了python的簡史,通俗的講python對於一個沒有開發經驗的小白來講是最容易上手的。 python在linux、windows、mac下的安裝,以及對於python2和python3的抉擇,(建議小白入手3)。 2.字元的編碼和解碼,可見# -*- coding:utf -8

關於CORS 應該注意

前言 對於跨域,隨著w3c的CORS的出現,相比較於有些年頭的jsonp,CORS以其簡單安全,支援post的優勢越來越收到大家的歡迎。具體如何CORS的原理和實現,直接推薦阮老師的文章,十分詳細。本文主要關注CORS實現過程中的幾個疑惑點。 預檢請求 背景 瀏覽器將CORS請求分成兩類:簡單請求(simpl

在使用靜態構造函數的時候應該註意

屬於 left 生成 意義 訪問修飾符 有意 訪問 div 數列   1、靜態構造函數既沒有訪問修飾符,也沒有參數。因為是.NET調用的,所以像public和private等修飾符就沒有意義了。      2、是在創建第一個類實例或任何靜態成員被引用時,.NET將自動調用

關於HTML5新手應該知道的知識

開發商 安卓 機會 至少 基本 scrip web前端 很難 出現   隨著移動互聯網的快速發展,HTML5迅速崛起,我們的生活的方方面面都被HTML5滲透著。HTML5在PC端、移動端上均應用廣泛,被稱為Web的未來。而隨著Google正式停止支持Swiffy,HTML5

新手學習嵌入式需要掌握的知識點

嵌入式開發 編程語言 嵌入式學習 linux內核 C語言 從事嵌入式開發十年了,有些感想寫出來,一則鞭策自己,讓自己看到自己的不足,認清以後的發展方向,二則深知很多朋友會像我當初一樣,為不知道儲備什麽知識而苦惱,所以寫點東西給這些朋友們提供參考。一些淺見。這裏覺得有幫助或者還在迷茫的朋友可

一個優秀團隊leader應該具備的素質

警告 價值 幫助 重要 問題 成員 戰鬥 至少 做的   首先,技術要過硬。畢竟一個團隊是在靠技術為別人創造價值的,一定程度上,團隊leader的技術能力決定了整個團隊的技術上限。leader對技術的堅持和追求很可能會影響團隊成員對技術的堅持和追求,至少leader技術過硬

設計模式大雜燴(24種設計模式的總結以及學習設計模式的建議)

  作者:zuoxiaolong8810(左瀟龍),轉載請註明出處,特別說明:本博文來自博主原部落格,為保證新部落格中博文的完整性,特複製到此留存,如需轉載請註明新部落格地址即可。            迄今為止

.net面向物件注意(好久沒寫了,再寫已經開始轉方向了,加油吧!)

一、類的定義          class前加一下訪問修飾符,不加預設private         類命名一般採用完整單詞,首字母大寫 二、類的成員(屬性,方法,索引器,事件,運算子,建構函

學習Python的過程中需要注意

  一、學習流程 1.學習過程中(看視訊、直播課程、書籍) 跟上思路 一旦發現不懂的概念, 先記錄在筆記中, 事後再查 搜尋引擎(不要在意百度,谷歌哪個逼格高;自己注意篩選就好) 查不到,或者查到不理解;來群裡吧(516107834)

線上PDF合併,你應該注意的三問題

工作中要把多個PDF檔案進行合併,很多人第一反應就是去網上搜索看看有沒有相應的軟體。其實有時候並不需要安裝軟體,現在很多網站可以進行線上PDF轉換。 那麼什麼樣的網站我們才能放心的使用呢? 1、操作簡單便利,不需進行安裝或設定,只要選擇檔案,就能合併頁面。 2、文件質量保證,合併後的

給即將學習大資料的建議

以下內容摘自一位學習大資料技術的朋友的感想和總結,文采飛揚、字字肺腑、產生共鳴。經本人同意,釋出至此,希望給很多站在大資料門口駐足、猶疑、徘徊的小夥伴一些建議,大資料行業發展不等人,要想改變現狀,現在出發,即可動手,大資料學習現在開始,為時未晚。 ——————————————————華麗的分割線

面試資料分析師崗位要注意

在資料分析行業摸爬滾打了些年成。將面試資料分析崗位前期的準備工作需要注意哪些要點,幫大家整理一下,希望對加入資料分析行業的小夥伴有幫助   ⑴ 不要輕易裸辭   雖然跳槽需要決心,但是也不要完全不給自己留一條後路,這樣會讓自己從一個坑陷入到另一個坑中去。 &n