Http協議入門、響應與請求行、HttpServletRequest對象的使用、請求參數獲取和編碼問題

1 課程回顧

web入門javascript

1)web服務軟件做用: 把本地資源共享給外部訪問css

2)tomcat服務器基本操做 :html

啓動:  %tomcat%/bin/startup.bat java

關閉: %tomcat%/bin/shutdown.batweb

訪問tomcat主頁:apache

http://localhost:8080瀏覽器

3)web應用目錄結構緩存

|- WebRoot   根目錄tomcat

|-靜態資源(html+css+javascript+images+xml)  能夠直接被瀏覽器訪問到的服務器

|-WEB-INF                                  不能夠直接被瀏覽器訪問到

|-classes     存放class字節碼文件

|-lib         存放jar包文件

web.xml      web應用的配置文件,配置servlet

4)Servlet技術: 用java語言開發動態資源的技術

開發一個Servlet程序的步驟:

1)建立一個java類,繼承HttpServlet類

2)重寫HttpServlet類的doGet方法

3)把寫好的servlet程序交給tomcat服務器運行!!!!

3.1 把編譯好的servlet的class文件拷貝到tomcat的一個web應用中。(web應用 的WEB-INF/classes目錄下)
3.2 在當前web應用的web.xml文件中配置servlet

<!-- servlet配置 -->

<servlet>

<servlet-name>HelloServlet</servlet-name>

<servlet-class>gz.itcast.HelloServlet</servlet-class>

</servlet>

<!--  servlet的映射配置 -->

<servlet-mapping>

<servlet-name> HelloServlet </servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

4)訪問servlet

http://localhost:8080/myweb/hello

今天的目標: http協議

2 Http協議入門

2.1 什麼是http協議

http協議: 對瀏覽器客戶端 和  服務器端 之間數據傳輸的格式規範

2.2 查看http協議的工具

1)使用火狐的firebug插件(右鍵->firebug->網絡)

2)使用谷歌的「審查元素」

3)使用系統自帶的telnet工具(遠程訪問工具)

a)telnet localhost 8080      訪問tomcat服務器

b)ctrl+]     回車          能夠看到回顯

c)輸入請求內容

GET /day09/hello HTTP/1.1

Host: localhost:8080

d)回車,便可查看到服務器響應信息。

2.3 http協議內容

請求(瀏覽器-》服務器)

GET /day09/hello HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

響應(服務器-》瀏覽器)

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Length: 24

Date: Fri, 30 Jan 2015 01:54:57 GMT

this is hello servlet!!!

3 Http請求

GET /day09/hello HTTP/1.1               -請求行

Host: localhost:8080                    --請求頭(多個key-value對象)

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

                                    --一個空行

name=eric&password=123456             --(可選)實體內容

3.1 請求行

GET /day09/hello HTTP/1.1

#http協議版本

http1.0:當前瀏覽器客戶端與服務器端創建鏈接以後,只能發送一次請求,一次請求以後鏈接關閉。

http1.1:當前瀏覽器客戶端與服務器端創建鏈接以後,能夠在一次鏈接中發送屢次請求。(基本都使用1.1)

#請求資源

URL:  統一資源定位符。http://localhost:8080/day09/testImg.html。只能定位互聯網資源。是URI 的子集。

URI: 統一資源標記符。/day09/hello。用於標記任何資源。能夠是本地文件系統,局域網的資源(//192.168.14.10/myweb/index.html), 能夠是互聯網。

#請求方式

常見的請求方式: GET 、 POST、 HEAD、 TRACE、 PUT、 CONNECT 、DELETE

經常使用的請求方式: GET  和 POST

表單提交:

<form action="提交地址" method="GET/POST">

<form>

GET   vs  POST 區別

1)GET方式提交

a)地址欄(URI)會跟上參數數據。以?開頭,多個參數之間以&分割。

GET /day09/testMethod.html?name=eric&password=123456 HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://localhost:8080/day09/testMethod.html

Connection: keep-alive

b)GET提交參數數據有限制,不超過1KB。

c)GET方式不適合提交敏感密碼。

d)注意: 瀏覽器直接訪問的請求,默認提交方式是GET方式

2)POST方式提交

a)參數不會跟着URI後面。參數而是跟在請求的實體內容中。沒有?開頭,多個參數之間以&分割。

POST /day09/testMethod.html HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://localhost:8080/day09/testMethod.html

Connection: keep-alive

name=eric&password=123456

b)POST提交的參數數據沒有限制。

c)POST方式提交敏感數據。

3.2 請求頭

Accept: text/html,image/*      -- 瀏覽器接受的數據類型

Accept-Charset: ISO-8859-1     -- 瀏覽器接受的編碼格式

Accept-Encoding: gzip,compress  --瀏覽器接受的數據壓縮格式

Accept-Language: en-us,zh-       --瀏覽器接受的語言

Host: www.it315.org:80          --(必須的)當前請求訪問的目標地址(主機:端口)

If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT  --瀏覽器最後的緩存時間

Referer: http://www.it315.org/index.jsp      -- 當前請求來自於哪裏

User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)  --瀏覽器類型

Cookie:name=eric                     -- 瀏覽器保存的cookie信息

Connection: close/Keep-Alive            -- 瀏覽器跟服務器鏈接狀態。close: 鏈接關閉  keep-alive:保存鏈接。

Date: Tue, 11 Jul 2000 18:23:51 GMT      -- 請求發出的時間

3.3 實體內容

只有POST提交的參數會放到實體內容中

3.4 HttpServletRequest對象

HttpServletRequest對象做用是用於獲取請求數據。

核心的API:

請求行:

request.getMethod(); 請求方式

request.getRequetURI()   / request.getRequetURL()   請求資源

request.getProtocol()   請求http協議版本

請求頭:

request.getHeader("名稱")   根據請求頭獲取請求值

request.getHeaderNames()    獲取全部的請求頭名稱

實體內容:

request.getInputStream()   獲取實體內容數據

3.5 service 和 doXX方法區別

HttpSevlet類的源碼:

protected void service(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

       //獲得請求方式

        String method = req.getMethod();

if (method.equals(METHOD_GET)) {

long lastModified = getLastModified(req);

if (lastModified == -1) {

// servlet doesn't support if-modified-since, no reason

// to go through further expensive logic

doGet(req, resp);

            } else {

long ifModifiedSince;

try {

                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

                } catch (IllegalArgumentException iae) {

// Invalid date header - proceed as if none was set

                    ifModifiedSince = -1;

                }

if (ifModifiedSince < (lastModified / 1000 * 1000)) {

// If the servlet mod time is later, call doGet()

// Round down to the nearest second for a proper compare

// A ifModifiedSince of -1 will always be less

                    maybeSetLastModified(resp, lastModified);

doGet(req, resp);

                } else {

                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

                }

            }

        } else if (method.equals(METHOD_HEAD)) {

long lastModified = getLastModified(req);

            maybeSetLastModified(resp, lastModified);

doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {

doPost(req, resp);

        } else if (method.equals(METHOD_PUT)) {

doPut(req, resp);       

        } else if (method.equals(METHOD_DELETE)) {

doDelete(req, resp);

        } else if (method.equals(METHOD_OPTIONS)) {

            doOptions(req,resp);

        } else if (method.equals(METHOD_TRACE)) {

            doTrace(req,resp);

        } else {

//

// Note that this means NO servlet supports whatever

// method was requested, anywhere on this server.

//

            String errMsg = lStrings.getString("http.method_not_implemented");

            Object[] errArgs = new Object[1];

            errArgs[0] = method;

            errMsg = MessageFormat.format(errMsg, errArgs);

            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

        }

    }

3.6 案例-獲取瀏覽器的類型(user-agent)

3.7 案例- 防止非法連接(referer)

第1次 CSDN/51CTO    ->   頁面(點擊下載)   -> 彈出廣告頁面(點擊此處下載) -> 開始下載 

第2次         直接點擊此處下載  ->  轉回廣告頁面  ->  開始下載

非法連接:

1)直接訪問下載的資源

2)不是從廣告頁面過來的連接

referer: 當前請求來自於哪裏。

3.8 傳遞的請求參數如何獲取

GET方式: 參數放在URI後面

POST方式: 參數放在實體內容中

獲取GET方式參數:

request.getQueryString();

獲取POST方式參數:

request.getInputStream();

問題:可是以上兩種不通用,並且獲取到的參數還須要進一步地解析。

因此可使用統一方便的獲取參數的方式:

核心的API:

request.getParameter("參數名");  根據參數名獲取參數值(注意,只能獲取一個值的參數)

request.getParameterValue("參數名「);根據參數名獲取參數值(能夠獲取多個值的參數)

request.getParameterNames();   獲取全部參數名稱列表

3.9 請求參數編碼問題

修改POST方式參數編碼:

request.setCharacterEncoding("utf-8");

修改GET方式參數編碼:

手動解碼:String name = new String(name.getBytes("iso-8859-1"),"utf-8");

4 Http響應

HTTP/1.1 200 OK                --響應行

Server: Apache-Coyote/1.1         --響應頭(key-vaule)

Content-Length: 24

Date: Fri, 30 Jan 2015 01:54:57 GMT

                                   --一個空行

this is hello servlet!!!                  --實體內容

4.1 響應行

     #http協議版本
#狀態碼: 服務器處理請求的結果(狀態)

常見的狀態:

200 :  表示請求處理完成並完美返回

302:   表示請求須要進一步細化。
404:   表示客戶訪問的資源找不到。

500:   表示服務器的資源發送錯誤。(服務器內部錯誤)

#狀態描述

      4.2 常見的響應頭

Location: http://www.it315.org/index.jsp   -表示重定向的地址,該頭和302的狀態碼一塊兒使用。

Server:apache tomcat                 ---表示服務器的類型

Content-Encoding: gzip                 -- 表示服務器發送給瀏覽器的數據壓縮類型

Content-Length: 80                    --表示服務器發送給瀏覽器的數據長度

Content-Language: zh-cn               --表示服務器支持的語言

Content-Type: text/html; charset=GB2312   --表示服務器發送給瀏覽器的數據類型及內容編碼

Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT  --表示服務器資源的最後修改時間

Refresh: 1;url=http://www.it315.org     --表示定時刷新

Content-Disposition: attachment; filename=aaa.zip --表示告訴瀏覽器如下載方式打開資源(下載文件時用到)

Transfer-Encoding: chunked

Set-Cookie:SS=Q0=5Lb_nQ; path=/search   --表示服務器發送給瀏覽器的cookie信息(會話管理用到)

Expires: -1                           --表示通知瀏覽器不進行緩存

Cache-Control: no-cache

Pragma: no-cache

Connection: close/Keep-Alive           --表示服務器和瀏覽器的鏈接狀態。close:關閉鏈接 keep-alive:保存鏈接

4.3 HttpServletResponse對象

HttpServletResponse對象修改響應信息:

響應行:

response.setStatus()  設置狀態碼

響應頭:

response.setHeader("name","value")  設置響應頭

實體內容:

response.getWriter().writer();   發送字符實體內容

response.getOutputStream().writer()  發送字節實體內容

4.4 案例- 請求重定向(Location

4.5 案例- 定時刷新(refresh)

4.6 案例-content-Type做用

總結:

http協議: 瀏覽器和服務器之間數據傳輸的格式規範

1)http請求:

格式:

請求行

請求頭

空行

實體內容(POST提交的數據在實體內容中)

重點:

使用HttpServletRequest對象: 獲取請求數據

2)http響應;

格式:

響應行

響應頭

空行

實體內容(瀏覽器看到的內容)

重點:

使用HttpServletResponse對象: 設置響應數據

相關文章
相關標籤/搜索