servlet&&HTTP協(xié)議&&Request對象學(xué)習(xí)

servlet&&HTTP協(xié)議&&Request對象學(xué)習(xí)


1.servlet 的體系結(jié)構(gòu)和介紹

Servlet
||
GenericServlet:將除service方法外的其余方法默認空實現(xiàn)召夹,只將service方法作為抽象(在正式開發(fā)的時候跪楞,我們不會使用這種方法),在使用的時候,直接直接定義一個類繼承g(shù)enericservlet類即可
||
HttpServlet:對http協(xié)議的一種封裝类少,簡化操作
處理了一個判斷請求的功能缀匕,在以前使用的servlet中當一個訪問來后艺蝴,創(chuàng)建完service方法腿准,無論是get方法請求還是 post方式請求,都需要進行判斷才能使用滓鸠,因為這兩種方式是不同的雁乡,所以我們需要判斷,而HttpServlet就在內(nèi)部對這個進行
編寫糜俗,直接有doget,dopost方法踱稍,來響應(yīng)不同方式的請求。而我們一般只寫一個
在doget中調(diào)dopost悠抹,或者在dopost中調(diào)doget珠月;


2.servlet的相關(guān)配置

  • 1.使用注釋,資源路徑可以有多個锌钮,也就是說使用不同的資源路徑桥温,創(chuàng)建同一個servlet,訪問同一個servlet
  • 2.在WebServlet注釋的定義中梁丘,可以看出侵浸,urlPattern是使用數(shù)組進行定義的所以旺韭,使用大括號對資源路徑進行賦值
    @WebServlet({"/demo4","/de4","/d4"})//* 使用這三個資源路徑都可以訪問到servlet資源路徑.
  • 3.路徑定義規(guī)則:的優(yōu)先級很低,使用之后掏觉,會優(yōu)先匹配別的資源路徑
    1./xxx : /
    :所有的資源路徑都可以訪問到當前的servlet
    2./xxx/xxx (目錄結(jié)構(gòu)) :/xxx/* :也可以使用通配符
    :/user/demo :多級目錄
    3.*.do(自定義后綴名) :demo.do

2.Http協(xié)議(Hyper Text Transfer Protocol)

  • 概念:超文本傳輸協(xié)議
    傳輸協(xié)議:定義了客戶端與服務(wù)器端通信的時候区端,請求消息和響應(yīng)消息的格式

  • http協(xié)議的特點
    1,基于tcp/ip協(xié)議的高級協(xié)議澳腹,也就是說面向連接的织盼,安全的,協(xié)議酱塔,進行通信的時候需要進行三次握手沥邻。
    2,默認端口號是:80羊娃。
    3唐全,基于請求/響應(yīng)模型:一次請求對應(yīng)一次響應(yīng),不會出現(xiàn)一次請求多次響應(yīng)的情況蕊玷,也不可能是對個請求一個響應(yīng)邮利。
    4,無狀態(tài)的:每次請求之間相互獨立垃帅,不能交互數(shù)據(jù)


    抓包延届,百度網(wǎng)頁的每一個資源都是一次請求
  • 歷史版本
    1.0:每一次請求響應(yīng)都是建立新的連接
    1.1:復(fù)用鏈接,將所有資源獲都傳輸成功后再斷開連接贸诚,但是每一個資源都是
    基于請求/響應(yīng)的模式


  • http請求/響應(yīng)消息數(shù)據(jù)格式(在使用瀏覽器方庭,開發(fā)者工具抓包的時候,瀏覽器太高級會導(dǎo)致我們?nèi)W(xué)習(xí)的時候很不便利赦颇,所以我們使用垃圾一點的瀏覽器二鳄,查看原始頭)
    1.請求行:(請求方式 請求url 請求協(xié)議和版本赴涵,在瀏覽器中會用其他的方式顯示媒怯,但是內(nèi)容還是這個內(nèi)容)
    如:GET /login.html?name=xzw http/1.1
    請求方式
    http協(xié)議有7種請求方式,而我們常見的方式有兩種髓窜,get扇苞,post方式
    GET方式:
    1,請求參數(shù)在請求行中寄纵,在url后 鳖敷,如:name=xzw
    2,請求的url長度有限制
    3程拭,不太安全(在url中可以之間看見參數(shù))
    POST方式:
    1定踱,請求參數(shù)在請求體中
    2,請求的url長度沒有限制
    3恃鞋,相對安全(在url中看不見參數(shù))

2崖媚,請求頭(鍵值對的形式存在亦歉,請求頭名稱,請求頭值)(就是客戶端瀏覽器發(fā)送給服務(wù)器的一些信息)
如:
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: Idea-9bab5137=3dd752db-249a-4508-851c-04dd5f28bc9e
Upgrade-Insecure-Requests: 1
If-Modified-Since: Sun, 26 Jan 2020 08:12:31 GMT
If-None-Match: W/"620-1580026351282"
Cache-Control: max-age=0
其中幾個常用的請求頭:
1.User-Agent:瀏覽器告訴服務(wù)器畅哑,我訪問你使用的瀏覽器版本信息肴楷,這個信息可以在服務(wù)器中獲取,然后根據(jù)這個信息解決服務(wù)器的兼容問題
2.accept:可以接受什么樣的文本
3.referer:告訴服務(wù)器荠呐,我當前的請求從哪里來赛蔫?
referer:http://localhost:8080/java_idea_request/input.html
作用:1.防盜鏈2.統(tǒng)計功能(判斷疊加)
說明:就是可以通過這個請求頭,去判斷當前請求是從哪個連接過來的泥张,可以防止盜鏈呵恢,和統(tǒng)計工作


3.請求空行:就是用來分隔請求頭和請求體的
4.請求體:封裝Post請求消息的請求參數(shù)



Tomcat服務(wù)器在請求和響應(yīng)是真正的過程

1.Tomcat服務(wù)器會根據(jù)請求的url資源路徑,創(chuàng)建對應(yīng)的servlet對象媚创。
2.Tomcat服務(wù)器會創(chuàng)建request和response對象瑰剃,request對象中會封裝請求消息數(shù)據(jù)。
3.Tomcat服務(wù)器將request對象和response對象傳遞給service方法筝野,并且調(diào)用service方法晌姚。
4.我們可以通過request對象獲取請求消息數(shù)據(jù),再通過response對象設(shè)置響應(yīng)信息數(shù)據(jù)
5.服務(wù)器在給瀏覽器做出響應(yīng)之前歇竟,從response對象中那程序員設(shè)置的響應(yīng)數(shù)據(jù)信息(也就是說挥唠,在瀏覽器還沒有接受到響應(yīng)的時候,是服務(wù)器先獲取到response中的數(shù)據(jù)焕议,在將數(shù)據(jù)響應(yīng)給瀏覽器)
(宝磨!就是說我以前認為的request對象就是請求,response對象就是響應(yīng)是不對的盅安,他們只是對請求和響應(yīng)的封裝)


  • request&&response對象的原理:
    1.request和response對象是服務(wù)器創(chuàng)建的唤锉,我們只是使用它
    2.request對象是用來獲取請求信息的,而response對象是用來設(shè)置響應(yīng)消息的

1.request對象

1.request繼承體系結(jié)構(gòu)


繼承關(guān)系

ServletRequest(接口)
|| 繼承
HttpServletRequest(接口)
|| 實現(xiàn)
RequestFacade(tomcat對象):我們實際使用的對象就是RequestFacade對象

  • RequestFacade對象在文檔中沒有别瞭,可以在tomcat的源碼中找到窿祥,也就是說這是tomcat對HttpServlet接口進行的實現(xiàn)

2.request對象的功能

  • 1.獲取請求行信息
    1,請求行信息包括:請求方式 請求url 請求協(xié)議和版本
    2蝙寨,方法:
@WebServlet("/request_demo2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.獲取請求頭方法
        String method = req.getMethod();
        System.out.println("方法:"+method);
        //2.獲取虛擬目錄V
        String contextPath = req.getContextPath();
        System.out.println("虛擬路徑:"+contextPath);
        //3.獲取資源路徑
        String servletPath = req.getServletPath();
        System.out.println("資源路徑:"+servletPath);
        //4.獲取get請求的請求參數(shù)
        String queryString = req.getQueryString();
        System.out.println("請求參數(shù)"+queryString);
        //5.獲取請求參數(shù)url
        String requestURI = req.getRequestURI();
        StringBuffer requestURL = req.getRequestURL();
        System.out.println("url:"+requestURL);
        System.out.println("uri:"+requestURI);
        //6.獲取協(xié)議和版本
        String protocol = req.getProtocol();
        System.out.println("協(xié)議和版本:"+protocol);
        //7.獲取客戶機的ip地址
        String remoteAddr = req.getRemoteAddr();
        System.out.println("客戶機的ip地址"+remoteAddr);
    }

(!):URL和URI的區(qū)別:URI的范圍更大
URL:統(tǒng)一資源定位符--http://localhost:8080/java_idea_request/request_demo2
中華人民共和國
URI :統(tǒng)一資源標識符--/java_idea_request/request_demo2
共和國

  • 2.獲取請求頭信息
  • 3.獲取請求體信息

  • 2.獲取請求頭信息
    1晒衩,請求頭信息 鍵值對的存在
    2,方法:兩個方法比較重要
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取所有的請求頭信息  Enumeration看做迭代器使用
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            //2.通過請求頭名稱獲取請求頭的值
            String header = request.getHeader(name);
            System.out.println(name+":"+header);
        }
    }
  • 案例:瀏覽器兼容和盜鏈問題還有統(tǒng)計數(shù)據(jù)的功能
    1墙歪,瀏覽器兼容的問題
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //案例一:瀏覽器兼容問題,就是要獲取User-agent的值,判斷他的包含那一種瀏覽器的名字
        String user_agent = request.getHeader("User-agent");
        if (user_agent!=null){
            if (user_agent.contains("Chrome")){
                System.out.println("谷歌瀏覽器");
            }
            else if (user_agent.contains("Firefox")){
                System.out.println("火狐瀏覽器");
            }
        }else {
            System.out.println("user_agent為空");
        }
    }

2,統(tǒng)計數(shù)據(jù)功能

public class RequestDemo5 extends HttpServlet {
    private  static   int a=0;
    private  static   int b=0;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //實現(xiàn)對百度和網(wǎng)易兩個網(wǎng)站的進入的訪問量統(tǒng)計
        //1.獲取Referer信息,然后判斷獲取的Referer中的信息听系,判斷是否在其中包含所需要的數(shù)據(jù),進行疊加
        String referer = request.getHeader("Referer");
        if (referer!=null){
        if (referer.contains("baidu")){
           this.a++;
        }else if(referer.contains("wangyi")){
            this.b++;
        }
        System.out.println("百度訪問:"+this.a+"次");
        System.out.println("網(wǎng)易訪問:"+this.b+"次");
        }
    }

3,防盜鏈

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取Referer的值
        String referer = request.getHeader("referer");
        System.out.println(referer);
        //2.判斷鏈接是否來自首頁
        if (referer!=null){
            if (referer.contains("java_idea_request")){
                //正常播放
                System.out.println("正常播放");
            }else {
                //請在優(yōu)酷首頁播放
                System.out.println("請在優(yōu)酷首頁進入");
            }
        }
    }
  • 3.獲取請求體信息
    請求體只有在Post請求方式虹菲,才會有請求體靠胜,在請求體中封裝了post請求的請求參數(shù)
    獲取步驟:
    1,獲取流對象,字符流或者是字節(jié)流
    2浪漠,從流對象中獲取數(shù)據(jù)
    方法:
public class RequsetDemo7 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取字符流對象:getReader();
        BufferedReader reader = request.getReader();//獲取字符流,獲取字符
        //2.獲取字節(jié)流對象getInputStream();
        // ServletInputStream inputStream = request.getInputStream();//獲取字節(jié)流,操作所有類型的文件
        String str = null;
        //2.獲取流對象中的數(shù)據(jù)
       while((str=reader.readLine())!=null){
           System.out.println(str);
       }
    }
  • 3.request 對象的其余功能
    1菠赚,獲取請求參數(shù),通用方法(以前的方法獲取的是一個字符串的形式郑藏,每一個鍵值對之間用&連接衡查,而且在使用的時候還要分成get方式和post方式)
    方法
   //1. 通用方式獲取請求參數(shù)
        String username = request.getParameter("name");
        String password = request.getParameter("password");
        System.out.println("username:"+username);
        System.out.println("password:"+password);
   //2.根據(jù)參數(shù)名獲取參數(shù)數(shù)組
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println("興趣是");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
   //3.獲取所有參數(shù)名
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String parameter_value = request.getParameter(name);
            System.out.println(name+":"+parameter_value);
        }
   //4.獲取所有參數(shù)的集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for (String string : strings) {
            String[] values = parameterMap.get(string);
            System.out.println(string);
            for (String value : values) {
                System.out.println("    "+value);
            }
        }

在使用的過程中,會出現(xiàn)中文亂碼的問題:


中文亂碼問題
  • get方式:tomcat8已經(jīng)將get方式的亂碼問題解決了
  • post方式:會亂碼必盖,主要原因是底層使用流的方式獲取數(shù)據(jù)
    解決方法:設(shè)置流的編碼拌牲,在獲取參數(shù)之前設(shè)置request的編碼
    request.setCharacterEncoding("utf-8");
    我么在使用的時候,無論是使用get方式還是post的方式都需要設(shè)置編碼
    效果:
    中文編碼正常


  • 4.請求轉(zhuǎn)發(fā)
    概念:一種在服務(wù)器內(nèi)部資源跳轉(zhuǎn)方式
    Aservlet
    ||兩個內(nèi)部資源之間的跳轉(zhuǎn)方式
    Bservlet

1.步驟:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Demo9的doGet方法調(diào)用成功");
        //1.獲取轉(zhuǎn)發(fā)器對象歌粥,并使用它進行轉(zhuǎn)發(fā),請求路徑是在虛擬路徑下的
        request.getRequestDispatcher("/requestDemo10").forward(request,response);
    }
控制臺

瀏覽器地址欄沒有發(fā)生變化

2塌忽,特點(面試題經(jīng)常與重定向之間進行比較)
1.瀏覽器的地址欄沒有發(fā)生變化
2.只能請求轉(zhuǎn)發(fā)到當前服務(wù)器的內(nèi)部資源中
3.轉(zhuǎn)發(fā)是一次請求(調(diào)用了請求路徑的service方法)


  • 5.共享數(shù)據(jù):request域,只能在請求轉(zhuǎn)發(fā)中實現(xiàn)失驶,也就是說只能在服務(wù)器內(nèi)部資源中使用
    域?qū)ο螅阂粋€有作用范圍的對象土居,可以在范圍內(nèi)共享數(shù)據(jù)
    request域:代表一次請求的范圍,一般用于請求轉(zhuǎn)發(fā)的多個資源中嬉探,共享數(shù)據(jù)
    方法(因為在請求轉(zhuǎn)發(fā)中擦耀,使用的都是當前請求的request對象,進行的請求轉(zhuǎn)發(fā)涩堤,所以一般用于請求轉(zhuǎn)發(fā)的多個資源中眷蜓,共享數(shù)據(jù))
//demo9
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Demo9的doGet方法調(diào)用成功");
        //1.存儲數(shù)據(jù)
        request.setAttribute("name","xzw");
        //3.通過鍵值移除域中的數(shù)據(jù)
        request.removeAttribute("name");
        //1.獲取轉(zhuǎn)發(fā)器對象,并使用它進行轉(zhuǎn)發(fā),請求路徑是在虛擬路徑下的
        request.getRequestDispatcher("/requestDemo10").forward(request,response);
    }
//demo10
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("進入demo10......");
        //2.獲取request域中的內(nèi)容
        Object name = request.getAttribute("name");
        if (name!=null){
            System.out.println(name.toString());
        }else {
            System.out.println("對象為空,可能已經(jīng)移除");
        }
    }
獲取成功

移除鍵值對后

  • 6.獲取servletcontext:
   //獲取servletContext對象
        ServletContext servletContext = request.getServletContext();
        System.out.println("servletContext:"+servletContext);
//結(jié)果:
servletContext:org.apache.catalina.core.ApplicationContextFacade@5a1fec1b


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胎围,一起剝皮案震驚了整個濱河市吁系,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌白魂,老刑警劉巖汽纤,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異福荸,居然都是意外死亡蕴坪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門逞姿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辞嗡,“玉大人,你說我怎么就攤上這事滞造。” “怎么了栋烤?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵谒养,是天一觀的道長。 經(jīng)常有香客問我,道長买窟,這世上最難降的妖魔是什么丰泊? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮始绍,結(jié)果婚禮上瞳购,老公的妹妹穿的比我還像新娘。我一直安慰自己亏推,他們只是感情好学赛,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吞杭,像睡著了一般盏浇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芽狗,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天绢掰,我揣著相機與錄音,去河邊找鬼童擎。 笑死滴劲,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的顾复。 我是一名探鬼主播哑芹,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捕透!你這毒婦竟也來了聪姿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤乙嘀,失蹤者是張志新(化名)和其女友劉穎末购,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虎谢,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡盟榴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了婴噩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擎场。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖几莽,靈堂內(nèi)的尸體忽然破棺而出迅办,到底是詐尸還是另有隱情,我是刑警寧澤章蚣,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布站欺,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏矾策。R本人自食惡果不足惜磷账,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贾虽。 院中可真熱鬧逃糟,春花似錦、人聲如沸蓬豁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庆尘。三九已至剃诅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驶忌,已是汗流浹背矛辕。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留付魔,地道東北人聊品。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像几苍,于是被迫代替她去往敵國和親翻屈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354