Servlet札記

Servlet概述

Servlet是由SUN公司提供的動(dòng)態(tài)web資源開(kāi)發(fā)技術(shù), 本質(zhì)上是一段java程序, 這段java程序無(wú)法獨(dú)立運(yùn)行, 必須放在Servlet容器(比如: tomcat服務(wù)器)中, 由容器調(diào)用才可以執(zhí)行!

[toc]


  • 簡(jiǎn)單開(kāi)發(fā)一個(gè)Servlet程序

1.開(kāi)發(fā)步驟

(1).寫一個(gè)類,實(shí)現(xiàn)一個(gè)Servlet接口,并添加未實(shí)現(xiàn) 的方法

(2).將編譯后類,放在WEB應(yīng)用中,并在WEB應(yīng)用web.xml文件中配置Servlet對(duì)外訪問(wèn)的虛擬路徑,將WEB應(yīng)用部署到虛擬主機(jī)中即可

2.開(kāi)發(fā)過(guò)程

(1)需求

瀏覽器向服務(wù)器發(fā)送一個(gè)請(qǐng)求, 訪問(wèn)FirstServlet, FirstServlet將表示當(dāng)前時(shí)間的字符串發(fā)送瀏覽器

(2)創(chuàng)建一個(gè)FirstServlet.java文件

(3)編寫FirstServlet類

  • 實(shí)現(xiàn)Servlet接口(或繼承Servlet接口的子類),并添加未實(shí)現(xiàn)的方法(java_ee_api文檔)
  • 實(shí)現(xiàn)Servlet中提供的處理請(qǐng)求方法service方法, 將表示當(dāng)前時(shí)間的字符串響應(yīng)給瀏覽器
  • 添加servlet類的包路徑和導(dǎo)入依賴包
package com.zn.servlet;
import java.io.*;
import java.util.*;
import javax.servlet.*;

public class FirstServlet extends GenericServlet{
    public void service(ServletRequest req, ServletResponse res) 
    throws ServletException, java.io.IOException{
        String datastr = new Date().toLocaleString();;
        res.getWriter().write(datastr);
    }
    
}

(4)編譯FirstServlet類

在cmd窗口通過(guò)命令編譯出現(xiàn)報(bào)錯(cuò)信息:

E:\>javac FirstServlet.java
FirstServlet.java:4: 錯(cuò)誤: 程序包javax.servlet不存在
import javax.servlet.*;
^
FirstServlet.java:6: 錯(cuò)誤: 找不到符號(hào)
public class FirstServlet extends GenericServlet{
                                  ^

原因是 javax.servlet這個(gè)包不存在, 所有下面出現(xiàn)了很多找不到符號(hào)錯(cuò)誤.
在tomcat服務(wù)器的lib目錄下有servlet的jar包, 可以設(shè)置包路徑:

設(shè)置包路徑
E:\>set classpath=...\apache-tomcat-7.0.53\lib\servlet-api.jar

再次編譯

/*帶包編譯:
            進(jìn)入到FirstServlet.java所在路徑
            命令: javac -d . FirstServlet.java 
            其中: -d是帶包編譯
                 點(diǎn)(.)表示編譯后的class存放在當(dāng)前目錄下*/

E:\>javac -d . FirstServlet.java

(5)將FirstServlet類放在WEB應(yīng)用中, 并在web.xml文件中配置Servlet對(duì)外訪問(wèn)的虛擬路徑

  • 將編譯好的class文件(包括包路徑)放在web應(yīng)用的classes目錄下
  • 在WEB應(yīng)用的web.xml文件中配置servlet對(duì)外訪問(wèn)的虛擬路徑:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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_3_0.xsd"
  version="3.0"
  metadata-complete="true">

  <welcome-file-list>
    <welcome-file>login.html</welcome-file>
  </welcome-file-list>
 
  <!-- servlet settings -->
  <servlet>
      <servlet-name>FirstServlet</servlet-name>
      <servlet-class>com.zn.servlet.FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>FirstServlet</servlet-name>
      <url-pattern>/FirstServlet</url-pattern>
    </servlet-mapping>

</web-app>

(7)將WEB應(yīng)用部署到虛擬主機(jī)中, 啟動(dòng)服務(wù)器, 通過(guò)瀏覽器訪問(wèn)FirstServlet

  • Servlet繼承結(jié)構(gòu)

Servlet繼承結(jié)構(gòu)
Servlet接口 – 通用的Servlet接口,提供了一個(gè)Servlet應(yīng)該具有的功能 
    | 
    |-- GenericServlet類, 實(shí)現(xiàn)了Servlet接口
        并實(shí)現(xiàn)了其中的大部分的方法,但是service方法沒(méi)有實(shí)現(xiàn), 
            |
            |-- HttpServlet類,實(shí)現(xiàn)了service方法
                在service方法中, 判斷請(qǐng)求方式
                根據(jù)不同的請(qǐng)求方式xxx調(diào)用不同doXxx
                   |
                   |-- XxxServlet類, 在開(kāi)發(fā)中,     
                       繼承HttpServlet, 
                       并覆蓋doGet和doPost方法, 
                       來(lái)處理GET請(qǐng)求和POST請(qǐng)求
  • Servlet調(diào)用過(guò)程

開(kāi)發(fā)一個(gè)Servlet, 放在WEB應(yīng)用中, 并將WEB應(yīng)用部署在服務(wù)器中, 啟動(dòng)服務(wù)器, 通過(guò)瀏覽器訪問(wèn)Servlet, 可以訪問(wèn)到Servlet處理的結(jié)果, 這個(gè)Servlet是如何被調(diào)用的, Servlet又是如何執(zhí)行的?


Servlet調(diào)用過(guò)程.png

1.Servlet生命周期

Servlet在第一次被訪問(wèn)時(shí)創(chuàng)建Servlet實(shí)例, 創(chuàng)建之后服務(wù)器會(huì)立即調(diào)用init方法進(jìn)行初始化的操作

創(chuàng)建之后, Servlet實(shí)例會(huì)一直駐留在服務(wù)器的內(nèi)存中, 為后續(xù)的請(qǐng)求服務(wù). 只要有請(qǐng)求來(lái)訪問(wèn)這個(gè)Servlet, 服務(wù)器就會(huì)調(diào)用service方法來(lái)處理請(qǐng)求, 直到服務(wù)器關(guān)閉, 或者WEB應(yīng)用被移出容器

隨著WEB應(yīng)用的銷毀, Servlet實(shí)例也會(huì)跟著銷毀, 在銷毀之前服務(wù)器會(huì)調(diào)用destroy方法進(jìn)行善后的處理

  • Servlet開(kāi)發(fā)細(xì)節(jié)

1.Servlet虛擬路徑的配置

Servlet在web.xml文件中虛擬路徑的配置方式可以有兩種方式:

(1) 直接寫一個(gè)路徑

后期需要通過(guò) /FirstServlet這個(gè)路徑來(lái)訪問(wèn)該Servlet

 <!-- servlet settings -->
  <servlet>
      <servlet-name>FirstServlet</servlet-name>
      <servlet-class>com.zn.servlet.FirstServlet</servlet-class>
  </servlet>
    <servlet-mapping>
      <servlet-name>FirstServlet</servlet-name>
      <url-pattern>/FirstServlet</url-pattern>
    </servlet-mapping>
  

(2) 還可以使用星號(hào)(*)匹配符來(lái)配置一個(gè)路徑,配置的方式有兩中:

  • 以斜杠(/)開(kāi)頭恶复,以斜杠星(/*)結(jié)尾

    /* , /a/* ...
  • 以星點(diǎn)后綴(*.后綴)的形式

    *.html , *.abc, *do...

使用星號(hào)匹配符可以使得路徑的訪問(wèn)變得更加靈活倘感, 但是也可能會(huì)導(dǎo)致一個(gè)url會(huì)被多個(gè)mapping所匹配奈惑。路徑的優(yōu)先級(jí)規(guī)則是什么筷登?

(1)哪一個(gè)更接近(更精準(zhǔn)绍刮、更像)哪一個(gè)起作用

(2)*.后綴的優(yōu)先級(jí)永遠(yuǎn)最低.

  • Request

代表HTTP請(qǐng)求的對(duì)象览爵。瀏覽器向服務(wù)器發(fā)送一個(gè)請(qǐng)求烈拒,服務(wù)器在調(diào)用Servlet的service方法處理請(qǐng)求之前嚷量,會(huì)創(chuàng)建代表Http請(qǐng)求的request對(duì)象陋桂,將所有的請(qǐng)求信息封裝在request對(duì)象中。

1.Request的繼承結(jié)構(gòu)

ServletRequest -通用的Request接口蝶溶,提供一個(gè)Request對(duì)象應(yīng)該具有的功能
    |
    |-- HttpServletRequest接口 - 
        繼承了ServletRequest接口, 
        在父接口的基礎(chǔ)上, 
        HttpServletRequest增加了一些和Http協(xié)議相關(guān)的方法

2.Request對(duì)象提供的功能

(1)獲取客戶端基本信息嗜历、獲取請(qǐng)求頭信息
/** Request獲取客戶機(jī)的基本信息、獲取請(qǐng)求頭信息
 * @author: zn
 * @time: 2018年8月16日,上午10:13:20
 */
public class RequestDemo1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.getRemoteAddr() -- 獲取ip地址
        String ip = request.getRemoteAddr();
        System.out.println("ip:"+ip);
        
        //2.getContxtPath() --獲取web應(yīng)用虛擬路徑
        String path = request.getContextPath();
        System.out.println("path:"+path);
        
        //3.getHader() --獲取請(qǐng)求頭信息
        String host = request.getHeader("host");
        System.out.println("host:"+host);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
(2)獲取請(qǐng)求參數(shù)
header 1 header 2
getParameter(String name) 通過(guò)請(qǐng)求參數(shù)的名字獲取對(duì)應(yīng)的參數(shù)值
getParameterValues(String name)
getParameterMap()
getParameterNames()
請(qǐng)求參數(shù)亂碼問(wèn)題

在通過(guò)request對(duì)象獲取請(qǐng)求參數(shù)時(shí), 如果參數(shù)中有中文數(shù)據(jù), 在獲取時(shí)就會(huì)出現(xiàn)亂碼, 其原因是由于瀏覽器發(fā)送參數(shù)時(shí)(編碼時(shí))使用的碼表 和 服務(wù)器在結(jié)束數(shù)據(jù)時(shí)(解碼時(shí))使用的碼表不一致造成的.


請(qǐng)求參數(shù)亂碼

解決方案:讓編碼時(shí)使用的碼表和解碼時(shí)使用的碼表保持一致即可

  • 手動(dòng)編解碼解決亂碼抖所,通用梨州,適應(yīng)POST和GET

(1)根據(jù)獲取的亂碼字符串,反向編碼得回正確的二進(jìn)制數(shù)據(jù)(iso8859-1)
(2) 將二進(jìn)制數(shù)組查詢utf-8碼表轉(zhuǎn)成字符串, 得回正確的數(shù)據(jù)

  • 如果請(qǐng)求方式是POST,可以通過(guò)request提供的方法解決

(1)request.setCharacterEncoding(“utf-8”);//這行代碼是通知服務(wù)器使用utf-8來(lái)接收請(qǐng)求

(2)必須放在任何獲取參數(shù)代碼之前田轧,否則無(wú)法生效

(3)GET提交的參數(shù)在請(qǐng)求行中的請(qǐng)求資源路徑后面拼接著, 不在請(qǐng)求實(shí)體內(nèi)容中,所有這行代碼對(duì)GET提交產(chǎn)生的亂碼不會(huì)起作用!

/** 通過(guò)Request獲取請(qǐng)求參數(shù)
 * @author: zn
 * @time: 2018年8月16日,上午10:33:44
 */
public class RequestDemo2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 通知服務(wù)器使用UTF-8接收請(qǐng)求實(shí)體內(nèi)容中的數(shù)據(jù),對(duì)POST提交的亂碼起作用
         */
        request.setCharacterEncoding("utf-8");
        
        //獲取用戶名
        String username = request.getParameter("username");
        //獲取用戶昵稱
        String nickname = request.getParameter("nickname");
        System.out.println("username:"+username+"\nnickname:"+nickname);
        
        //獲取愛(ài)好
        String[] likes = request.getParameterValues("like");
        System.out.println("likes"+Arrays.toString(likes));
        
        //================= GET亂碼解決 =======================//
        byte[] bytes = username.getBytes("iso8859-1");
        username = new String(bytes,"utf-8");
        System.out.println("GET-> username:"+username);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
![請(qǐng)求轉(zhuǎn)發(fā)](https://upload-images.jianshu.io/upload_images/4495072-928577dda76eb86e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

(3)實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)
  • 請(qǐng)求重定向:實(shí)現(xiàn)資源的跳轉(zhuǎn)

  • 請(qǐng)求轉(zhuǎn)發(fā):實(shí)現(xiàn)資源的跳轉(zhuǎn)暴匠,并且是服務(wù)器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市傻粘,隨后出現(xiàn)的幾起案子每窖,更是在濱河造成了極大的恐慌,老刑警劉巖弦悉,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窒典,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡稽莉,警方通過(guò)查閱死者的電腦和手機(jī)瀑志,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)污秆,“玉大人劈猪,你說(shuō)我怎么就攤上這事』旌荩” “怎么了岸霹?”我有些...
    開(kāi)封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)将饺。 經(jīng)常有香客問(wèn)我贡避,道長(zhǎng)痛黎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任刮吧,我火速辦了婚禮湖饱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杀捻。我一直安慰自己井厌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布致讥。 她就那樣靜靜地躺著仅仆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垢袱。 梳的紋絲不亂的頭發(fā)上墓拜,一...
    開(kāi)封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音请契,去河邊找鬼咳榜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛爽锥,可吹牛的內(nèi)容都是我干的涌韩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼氯夷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼臣樱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肠槽,我...
    開(kāi)封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤擎淤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后秸仙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體嘴拢,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年寂纪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了席吴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捞蛋,死狀恐怖孝冒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拟杉,我是刑警寧澤庄涡,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站搬设,受9級(jí)特大地震影響穴店,放射性物質(zhì)發(fā)生泄漏撕捍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一泣洞、第九天 我趴在偏房一處隱蔽的房頂上張望忧风。 院中可真熱鬧,春花似錦球凰、人聲如沸狮腿。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缘厢。三九已至,卻和暖如春义钉,著一層夾襖步出監(jiān)牢的瞬間昧绣,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工捶闸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拖刃。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓删壮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親兑牡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子央碟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)均函,斷路器亿虽,智...
    卡卡羅2017閱讀 134,702評(píng)論 18 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,435評(píng)論 1 92
  • 從三月份找實(shí)習(xí)到現(xiàn)在苞也,面了一些公司洛勉,掛了不少,但最終還是拿到小米如迟、百度收毫、阿里、京東殷勘、新浪此再、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,277評(píng)論 11 349
  • 上一章 目錄 下一章 第二章:會(huì)飛的花草 懸崖峭壁下的溪谷里玲销,一只小鳥(niǎo)——紅點(diǎn)输拇,伴著一棵小草芽——翠芽,他們的...
    繭破閱讀 311評(píng)論 1 3
  • 小B聯(lián)系我的時(shí)候议慰,我還在廣東佛山那邊的一個(gè)路邊廣告店做設(shè)計(jì)學(xué)徒,老板是一個(gè)來(lái)自江西的30多歲漢子奴曙,老婆是廣東人别凹,兩...
    朝聞晨露夜聽(tīng)雨閱讀 372評(píng)論 0 1