1. 程式人生 > >Servlet之forward、sendRedirect、 include區別與使用

Servlet之forward、sendRedirect、 include區別與使用

林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

servlet中的請求轉發主要有三種方式:
1、 forward:是指轉發,將當前request和response物件儲存,交給指定的url處理。並沒有表示頁面的跳轉,所以位址列的地址不會發生改變。
2、 redirect:是指重定向,包含兩次瀏覽器請求,瀏覽器根據url請求一個新的頁面,所有的業務處理都轉到下一個頁面,位址列的地址會變發生改變。
3、 include:意為包含,即包含url中的內容,進一步理解為,將url中的內容包含進當前的servlet當中來,並用當前servlet的request和respose來執行url中的內容處理業務.所以不會發生頁面的跳轉,位址列地址不會發生改變。


1、客戶端跳轉

        在Servlet中如果要想進行客戶端跳轉,直接使用HttpServletResponse介面的sendRedirect()方法即可,要注意的是:此跳轉只能傳遞session範圍的屬性,無法傳遞request範圍屬性。
        這個過程也可叫做重定向。重定向是指頁面重新定位到某個新地址,之前的請求失效,進入一個新的請求,且跳轉後瀏覽器位址列內容將變為新的指定地址。重定向是通過HttpServletResponse物件的sendRedirect()來實現,該方法相當於瀏覽器重新發送一個請求response.sendRedirect(path);


該圖的互動過程如下:
① 瀏覽器訪問Servlet1。
② Servlet1想讓Servlet2為客戶端服務。
③ Servlet1呼叫sendRedirect()方法,將客戶端的請求重定向到Servlet2。
④ 瀏覽器訪問Servlet2。
⑤ Servlet2對客戶端的請求做出響應。這種方式是在客戶端作的重定向處理。該方法通過修改HTTP協議的HEADER部分,對瀏覽器下達重定向指令的,讓瀏覽器對在location中指定的URL提出請求,使瀏覽器顯示重定向網頁的內容。該方法可以接受絕對的或相對的URLs。如果傳遞到該方法的引數是一個相對的URL,那麼Web container在將它傳送到客戶端前會把它轉換成一個絕對的URL。

由於是客戶端跳轉,從執行程式結果可以發現,跳轉後的位址列是會發生變化的,只能接收session屬性範圍的內容,不能接收request屬性範圍的內容

2、伺服器跳轉

      伺服器跳轉也可叫做請求轉發。請求轉發是指將請求再轉發到另一資源(一般為JSP或Servlet)。此過程依然在同一個請求範圍內,轉發後瀏覽器位址列內容不變。請求轉發使用RequestDispatcher介面中的forward()方法來實現,該方法可以把請求轉發到另外一個資源,並讓該資源對瀏覽器的請求進行響應

RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request,response);
request.getRequestDispatcher(path) .forward(request,response);


①瀏覽器訪問Servlet1。
② Servlet1想讓Servlet2對客戶端的請求進行響應,於是呼叫forward()方法,將請求轉發給Servlet2進行處理。
③ Servlet2對請求做出響應。
互動過程可以看出,呼叫forward()方法,對瀏覽器來說是透明的,瀏覽器並不知道為其服務的Servlet已經換成Servlet2了,它只知道發出了一個請求,獲得了一個響應。顯示的URL始終是原始請求的URL。

        伺服器跳轉後,位址列不發生變化,而且此時在跳轉後的JSP檔案中接收到session及request範圍的屬性。此外,sendRedirect()方法和forward()方法還有一個區別,那就是sendRedirect()方法不但可以在位於同一主機上的不同Web應用程式之間進行重定向,而且可以將客戶端重定向到其他伺服器上的Web應用程式資源。

3、二者區別總結


4、測試範例

在eclipse下新建一個web專案


首先編寫三個servlet介面:分別是

登入驗證:login.java;

package com.mucfc;
/**  
*功能  登入驗證
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.24 
*/
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/LoginCheck")
public class LoginCheck extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public LoginCheck() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("gbk");  
        response.setCharacterEncoding("gbk");  
        response.setContentType("text/html;charset=gbk");  
        String username = request.getParameter("username");  
        String password = request.getParameter("password");  
        PrintWriter pw = response.getWriter();  
        pw.write("include包含。");  
        if(username.equals("lin")&&password.equals("123")){  
        //include測試  
            request.getRequestDispatcher("/success").include(request, response);  
       //forward測試
        //RequestDispatcher dispatcher=request.getRequestDispatcher("/success");
       // dispatcher.forward(request, response); 
        }else{  
            //在sendRedict中url前必須加上當前web程式的路徑名.....  
            response.sendRedirect(request.getContextPath()+"/fail");  
        }  
	}


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

}
登入成功:success.java;
package com.mucfc;
/**  
*功能  登入成功
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.24 
*/
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/success")
public class success extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public success() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	  
		//設定編碼格式  
        response.setContentType("text/html;charset=GBK");           
        //返回html頁面  
        response.getWriter().println("<html>");  
        response.getWriter().println("<head>");     
        response.getWriter().println("<title>登入資訊</title>");      
        response.getWriter().println("</head>");    
        response.getWriter().println("<body algin=center>");     
        response.getWriter().println("歡迎登入成功!!!");    
        response.getWriter().println("</body>");    
        response.getWriter().println("</html>");  
	}


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

}
登入失敗:fail.java;
package com.mucfc;
/**  
*功能  登入失敗
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.24 
*/
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/fail")
public class fail extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
 
    public fail() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//設定編碼格式  
        response.setContentType("text/html;charset=GBK");           
        //返回html頁面  
        response.getWriter().println("<html>");  
        response.getWriter().println("<head>");     
        response.getWriter().println("<title>登入資訊</title>");      
        response.getWriter().println("</head>");    
        response.getWriter().println("<body algin=center>");     
        response.getWriter().println("登入失敗!!!");    
        response.getWriter().println("</body>");    
        response.getWriter().println("</html>");  
	}


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

}

2、登入初始化介面Login.jsp

<%@ page language="java" contentType="text/html; charset=GBK"
    pageEncoding="GBK"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<center><title>MVC登入例項</title></center>
</head>
<body>
<center><h2>使用者登入程式</h2></center>
<center>
<form action="LoginCheck" method="post" >
使用者名稱:<input type="text" name="username"><br>
 密 碼:<input type="password" name="password"><br>
 <input type="submit" value="登入">
 <input type="reset" value="重置">
</form>
</center>
</body>
</html>
3、web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <welcome-file-list>
    <welcome-file>Login.html</welcome-file>
    <welcome-file>Login.htm</welcome-file>
    <welcome-file>Login.jsp</welcome-file>
  </welcome-file-list>
  
 <servlet>
    <servlet-name>LoginCheck</servlet-name>
    <servlet-class>com.mucfc.LoginCheck</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginCheck</servlet-name>
    <url-pattern>/servlet/LoginCheck</url-pattern>
  </servlet-mapping>
  
    <servlet>
    <servlet-name>success</servlet-name>
    <servlet-class>com.mucfc.success</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>success</servlet-name>
    <url-pattern>/servlet/success</url-pattern>
  </servlet-mapping>
  
     <servlet>
    <servlet-name>fail</servlet-name>
    <servlet-class>com.mucfc.fail</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>fail</servlet-name>
    <url-pattern>/servlet/fail</url-pattern>
  </servlet-mapping> 
  
</web-app>

執行後的介面,輸入後會先跳轉到LoginCheck


執行後如果輸入正確的使用者名稱密碼,則執行include方法,介面顯示:include包含。 登入成功!並且位址列地址未改變,若是輸入錯誤登入名或者密碼,介面顯示:登入失敗! 並且位址列地址改變。其中要注意的是sendRedirect方法中在要跳轉的頁面url前必須加上當前web程式路徑名,這個路徑通過request.getContextPath()可以得到。

 

登入時輸入正確資訊,則跳轉的頁面地址不變,顯示:登入成功!不包含url中的內容。

如果把其中include方法改為forward方法:

     RequestDispatcher dispatcher=request.getRequestDispatcher("/success");
     dispatcher.forward(request, response); 



 登入時輸入正確資訊,則跳轉的頁面地址不變,顯示:登入成功!不包含url中的內容。

登入時輸入錯誤資訊,則跳轉的頁面地址改變,顯示:登入失敗!包含url中的內容。

總結如下:

redirect與include、forward的區別在於是不是同一個Request,redirect會有兩次互動。

include與forward的區別在於輸出的內容,include包含本身servlet與跳轉頁面內容的結果,而forward不包含本身servlet的內容。

林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

相關推薦

ServletforwardsendRedirect include區別使用

林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankakaservlet中的請求轉發主要有三種方式:1、 forward:是指轉發,將當前request和r

jsp(4):頁面跳轉 重定向forward超連結響應等待的區別使用

頁面跳轉有四種:jsp動作指令forward、html的超連結、重定向、response的響應跳轉。<jsp:forward>重定向格式:response.sendRedirect("要跳轉的介面");為了方便說明重定向和forward的不同,我們以實現使用者登陸

接口抽象類的區別共同點

png 功能 系統 上層 http image 重寫 常量 div 接口和抽象類都是繼承樹的上層,他們的共同點如下:1) 都是上層的抽象層。2) 都不能被實例化3) 都能包含抽象的方法,這些抽象的方法用於描述類具備的功能,但是不比提供具體的實現。他們的區別如下:1) 在抽

黑盒測試白盒測試單元測試集成測試系統測試驗收測試的區別聯系

角色 同時 驗收 center 調試 需求 lan 說明書 錯誤 黑盒測試、白盒測試、單元測試、集成測試、系統測試、驗收測試的區別與聯系   接下來為大家細心講述一下各種測試應用的環境及作用。 一、測試環境和角色 黑盒測試、白盒測試、單元測試、集成測試、系統測試、

PHP中VC6VC9TSNTS版本的區別用法詳解

進行 系統資源 stc 詳解 ron 線程安全 info 啟動 win 1. VC6與VC9的區別: VC6版本是使用Visual Studio 6編譯器編譯的,如果你的PHP是用Apache來架設的,那你就選擇VC6版本。 VC9版本是使用Visual Studio 20

終端(terminal)shelltty控制臺(console)bash之間的區別聯系

https 電視 min ksh ctrl+ 編輯 按鈕 urn 用戶 1、終端(termimal)= tty(Teletypewriter, 電傳打印機),作用是提供一個命令的輸入輸出環境,在linux下使用組合鍵ctrl+alt+T打開的就是終端,可以認為termina

delphi “div”“mod”“\”除法運算子的區別使用方法

delphi中和除法相關的算術運算子有:div、mod和符號“\”,下面分別對他們的作用、運算元型別和返回值型別進行一下介紹:div:對2個整數進行除,取商,運算元需是integer型別,返回值也是integer。\:2個數進行除,取商,運算元可以為integer和real,返回值為real型別。mod:取2

雜談(第1篇) | 程序執行緒協程的區別聯絡

作為程式設計師,在面試的時候經常被問到:說說程序、執行緒、協程的區別。下面我們就總結一下。 1.面試答案     1.1  程序與執行緒的區別 總述:執行緒是程序的一個實體,一個程序至少有一個執行緒。 1.根本區別;程序是作業系統資源分配的基本

web伺服器應用伺服器web容器反向代理伺服器區別聯絡

Web伺服器工作原理 HTTP協議基於TCP協議上,是一個應用層協議,用於使用者代理和Web伺服器進行通訊。Web伺服器通常採用一問一答的方式進行工作: 在使用者代理上使用者發起資源請求,請求內容包括但不限於:指定資源的唯一標識URI,指明動作型別(GET/POS

訓練集驗證集測試集的區別應用

0. 前言 最近一直在看論文、跑模型和做工程,很久沒有來發部落格了。但是在日常的學習和交流中,我感覺大家更加會關注當今最新的模型,最先進的演算法,但是對於一些非常基礎的內容的理解還不夠透徹,我也是想借此機會梳理清楚一些內容。 今天想講的是資料集的劃分,即訓練集,驗證集和測試集分別是啥

程式程序執行緒的區別聯絡

程式 程式並不能單獨執行,只有將程式載入到記憶體中,系統為他分配資源後才能夠執行,這種執行的程式稱之為程序, 也就是說程序是系統進行資源分配和排程的一個獨立單位,每個程序都有自己單獨的地址空間。 所以說程式與程序的區別在於,程式是指令的集合,是程序執行的靜態描述文字,

NIoBioaio 的原理及區別應用場景

在高效能的IO體系設計中,有幾個名詞概念常常會使我們感到迷惑不解。具體如下:  序號 問題 1 什麼是同步? 2 什麼是非同步? 3 什麼是阻塞? 4 什麼是非阻塞? 5 什麼是同步阻塞? 6 什麼是同步非阻

Web伺服器應用伺服器Web容器反向代理伺服器區別聯絡[轉]

我們知道,不同膚色的人外貌差別很大,而雙胞胎的辨識很難。有意思的是Web伺服器/Web容器/Web應用程式伺服器/反向代理有點像四胞胎,在網路上經常一起出現。本文將帶讀者對這四個相似概念如何區分。 一文看懂web伺服器、應用伺服器、web容器、反向代理伺服器區

遞迴迭代動態規劃的區別聯絡

一、定義 遞迴:程式呼叫自身,從頂部將問題分解,通過解決掉所有分解出來的小問題,來解決整個問題。 迭代:利用變數的原值推算出變數的一個新值。遞迴中一定有迭代,但是迭代中不一定有遞迴。 動態規劃:通常與遞迴相反,其從底部開始解決問題。將所有小問題解決掉,進而解決的

Python 例項方法類方法靜態方法的區別作用

Python中至少有三種比較常見的方法型別,即例項方法,類方法、靜態方法。它們是如何定義的呢?如何呼叫的呢?它們又有何區別和作用呢?且看下文。 首先,這三種方法都定義在類中。下面我先簡單說一下怎麼定義和呼叫的。(PS:例項物件的許可權最大。) 例項方法 定義:第一個引數必

gcc中printf/scanfprintf_P/scanf_P的區別用法

   從字面意思來看 printf/scanf是對RAM的操作,即把記憶體資料輸出/輸入到RAM。 printf_P/scanf_P是對ROM的操作,即把ROM資料輸出/輸入到ROM #include <avr/pgmspace.h> 這個標頭檔案用來訪問

keypresskeydownkeyup之間的區別聯絡

雖然從字面理解, KeyDown是按下一個鍵的意思, 但實際上二者的根本區別是, 系統由KeyDown返回鍵盤的程式碼, 然後由TranslateMessage函式翻譯成成字元, 由KeyPress返回字元值. 因此在KeyDown中返回的是鍵盤的程式碼, 而KeyPress返回的是ASCI

軟體測試 -- 比較一下黑盒測試白盒測試單元測試整合測試系統測試驗收測試的區別聯絡

黑盒測試:已知產品的功能設計規格,可以進行測試證明每個實現了的功能是否符合要求。 白盒測試:已知產品的內部工作過程,可以通過測試證明每種內部操作是否符合設計規格要求,所有內部成分是否以經過檢查。 軟體的黑盒測試意味著測試要在軟體的介面處進行。這種方法是把測試物件看做一個黑盒子,測試人員完全不考慮程式內部的邏

MVCMVPMVVM 三者解析 區別聯絡

理想的MVC模式中VC之間沒有直接依賴(沒有單向依賴),但現實中做不到。Native應用要一般由View分發事件給Controller,Controller要決定那些View使用者可見。 Web應用中情況好一點。使用者可以直接通過url直接訪問Controll

資料快取sessionStoragelocalStoragecookiesession間的區別聯絡

 核心三步曲:建立-獲取-清除(回收) sessionStorage.setItem("key","123"); sessionStorage.getItem("key"); sessionStorage.removeItem("key"); sessionStora