1. 程式人生 > >servlet中轉發請求與重定向小結

servlet中轉發請求與重定向小結


請求轉發:
方式:request.getRequestDispacther("/test.jsp").forword(request,response); 
過程分析:客戶端發出一個請求reqeust到伺服器,伺服器找到相應的Servlet處理資料,然後呼叫
request.getRequestDispacther("/test.jsp").forword(request,response); 
從字面上也可以理解:帶著request,response向test.jsp前進!進!(完全自己意淫的,不要當真...)
請求和響應都被送到另一個Servlet或者jsp(特殊的Servlet)中。這樣整個過程中,只有一個請求、一個響應,所有 Servlet和JSP都共享它倆(好可憐..偷笑

),所以所有的Servlet和Jsp都可以從request中獲取請求引數。


重定向:
方式:response.sendRedirect("test.jsp");
過程分析:客戶端發出一個請求reqeust到伺服器,伺服器找到相應的Servlet處理資料,到這裡都是一樣一樣的。然後呼叫
response.sendRedirect("test.jsp");
從字面上也可以理解:返回客戶端一個叫test.jsp的頁面。(不要當真...)
注意,這個方法是response的方法哦,這個時候它就已經給客戶端響應了,這一次的請求、響應過程已經結束了!
但是呢,臨了的時候它還告訴客戶端,你要去test.jsp哈(死了都不老實,難怪活不過兩集敲打)
於是乎客戶端又向伺服器發出一次去test.jsp的請求,根據http(s)特性,每次請求之間是完全獨立的,所以本次請求到test.jsp頁面,是不會再獲取上一次request中的引數的。


不同點列舉:
1、安全性
顯然 請求轉發更安全。一個請求在完成的過程中可能會通過多個Servlet,最終到達一個jsp頁面,在整個過程中,url是不會變的。這樣從客戶端就看不出來伺服器是由哪些資源來處理資料的。
而重定向更遵循”所見即所得“,也就是你所請求的資源,就是url顯示的。比如重定向到test.jsp,url可能就是“localhost:8080/project_name/test/test.jsp”.這樣不僅不安全,也限制了伺服器端的靈活性。
2、可定位範圍
重定向範圍更廣,應該說它可以重定向到任何有效的url。
而轉發就比較杯具了,只能在伺服器內部轉發。


轉發或重定向的url問題:
web.xml中有如下配置:
    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>com.test.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/servlet/testServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>test</servlet-name>
        <jsp-file>/WEB-INF/test.jsp</jsp-file>//直接指向jsp的標籤和指向servlet的標籤是不同的
    </servlet>
    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/servlet/test.d</url-pattern>
    </servlet-mapping>

客戶端發出請求,url:localhost/project_name/servlet/testServlet(注意這個url,下面的url都和這個連結有著密切的關係)。
伺服器接收到請求並匹配TestServlet去處理這個請求。然後準備請求轉發。
1、url為伺服器外的目標,比如百度。
url="www.baidu.com";
request.getRequestDispacther(url).forword(request,response); 
這樣是不會成功的。轉發的最終請求連結是:localhost/project_name/servlet/www.baidu.com(這裡字首是亮點)。完全沒有跳轉到百度的意思...
那試試重定向吧:
url="www.baidu.com";
response.sendRedirect(url);
也不行...最終請求還是:localhost/project_name/servlet/www.baidu.com,根本沒這個url地址嘛!
修改url:
url="https://www.baidu.com";
request.getRequestDispacther(url).forword(request,response); 
還是不成功。轉發的最終請求連結是:localhost/project_name/servlet/https:/www.baidu.com(還被偷吃了一個/)。
那試試重定向吧:
url="https://www.baidu.com";
response.sendRedirect(url);
成了!就是這麼無耐!哼!
2、url為伺服器內的目標
url="servlet/test.d";
request.getRequestDispacther(url).forword(request,response); 
不成功。轉發的最終請求連結是:localhost/project_name/servlet/servlet/test.d,顯然不是一個可用的url嘛。
因為同樣的原因,重定向也是失敗的。
修改url:
url="test.d";
都成功。
小結:
1、
1-1、如果下一個地址是伺服器以外的,則只能選擇重定向了。
1-2、如果是伺服器內的地址,要看是否需要第一次請求時的請求引數而定,推薦使用請求轉發。
2、
2-1、對於新目錄中沒有http(s)的:
進入該servlet時的請求是:http(s)://ip:port/project_name/preA/preB/serv.do,
Servlet中下個目標地址是url,則轉發或重定向的最終請求地址是:http(s)://ip:port/project_name/preA/preB/url.
2-2、對於下個目標地址中有http(s)的:
最終請求地址:
轉發:http(s)://ip:port/project_name/preA/preB/url(url如果有連續的/會被刪除一個)
重定向:url




addtion:
不管是重定向還是轉發,並沒有return這樣功能,如果後面有程式碼的話,還會繼續執行,直到所有程式碼執行完畢。
但是不要出現既有重定向又有請求轉發的情況,不管哪個出現在前哪個出現在後,伺服器會蒙*的。