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; 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" )){ request.getRequestDispatcher("/success" ).include(request, response); }else { response.sendRedirect(request.getContextPath()+"/fail" ); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
登录成功:success.
java;
package com.mucfc; 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" ); 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; 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" ); 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的内容。