JAVA的服务重定向:使用forward()方法转发请求和使用sendRedirect()方法重定向的区别

使用RequestDispatche r的 forward()方法转发请求和使用HttpServletResponse的 sendRedirect()方法重定向均可以使页面转到另一个页面,如今收集一下二者的不一样:css

一.RequestDispatcher.forward()方法
        forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,而后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,因此它的地址栏中仍是原来的地址。
        服务方(如:servlet)将请求转发到同一个WEB应用程序中另外一个Servlet(或:JSP)--第三方 进行处理(该过程浏览器方-客户方并不知道),让这个第三方直接将结果返回给浏览器方。
一般在servlet中使用的代码是:html

request.getRequestDispatcher(跳转页面的Url).foward(request,response);

如何获得RequestDispatcherjava

有三种方法能够获得Request Dispatcher对象。web

        1.javax.servlet. ServletRequest的getRequestDispatcher(String path)方法,其中path能够是相对路径,但不能越出当前Servlet上下文。若是path以“/”开头,则解析为相对于当前上下文的根。chrome

        2.javax.servlet. ServletContext的getRequestDispatcher(String path)方法,其中path必须以“/”开头,路径相对于当前的Servlet上下文。能够调用ServletContext的getContext(String uripath)获得另外一个Servlet上下文,并能够转向到外部上下文的一个服务器资源连接。浏览器

        3.使用javax.servlet. ServletContext的getNamedDispatcher(String name)获得名为name的一个Web资源,包括Servlet和JSP页面。这个资源的名字在Web应用部署描述文件web.xml中指定。服务器

        这三种方法的使用有细微的差异。好比一个应用的配置文件web.xml,其中定义了两个Servlet,名字分别为FirstServlet和SecondServlet,对应的类分别为org.javaresearch. redirecttest.ServletOne和org. javaresearch.redirecttest.ServletTwo。能够在浏览器中经过相似于下面的连接访问:http://localhost:8080/servlet/firstservlet/
使用1中方法,例如在firstservlet能够写入下面的代码:session

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

        此时控制权将转向到第二个Servlet了。app

        使用2中的方法,能够从Servlet Context中获得RequestDispatcher代码以下:jsp

RequestDispatcher rd = getServletContext().getRequest
Dispatcher("/servlet/secondservlet");
rd.forward(request, response);

        使用3中的方法,从上面的web. xml配置文件能够看到定义了两个Servlet,名字分别为FirstServlet和SecondServlet,因此能够获得命名的Dispatcher:

RequestDispatcher rd = getServletContext().getNamedDispatcher("SecondServlet");
rd.forward(request, response);

        这样也能够重定向到SecondServlet了。

 

二.sendRedirect()方法
        response.sendRedirect(跳转页面URL)
        就是服务端根据逻辑,发送一个状态码(Location ,状态码320),告诉浏览器从新去请求那个地址,通常来讲浏览器会用刚才请求的全部参数从新请求,因此session,request参数均可以获取。
        服务方(如:servlet)直接将目标URL发回浏览器,让浏览器本身自动从新向目标URL发出HTTP请求。
        重定向是做为不一样请求来看待的。


三.如何选择
        RequestDispatcher.forward()方法和HttpServletResponse.sendRedirect()方法的区别是:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是彻底的跳转,浏览器将会获得跳转的地址,并从新发送请求连接。这样,从浏览器的地址栏中能够看到跳转后的连接地址。因此,前者更加高效,在前者能够知足须要时,尽可能使用Request Dispatcher.forward()方法,而且,这样也有助于隐藏实际的连接。在有些状况下,好比,须要跳转到一个其它服务器上的资源,则必须使用HttpServletResponse.sendRequest()方法。

PS:

1.在过滤器中用sendRedirect跳到指定的页面,通常都能正常显示,以下所示。

String contextPath = httpServletRequest.getContextPath();
httpServletResponse.sendRedirect(contextPath + "/alert.html");

        但在过滤器中用forward跳到指定的页面,因为指定的页面的contextPath和当前请求的contextPath不一样,致使跳到指定的页面不能加载页面须要的其它资源文件,如.css、.js、.img等资源。

request.getRequestDispatcher("/error.jsp").forward(httpServletRequest, httpServletResponse);

        forward去的页面,需设置base,以下所示:

复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isErrorPage="true"%>
<%
    request.setCharacterEncoding("utf-8");
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
    <base href="<%=basePath%>">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
...
复制代码

2.forward传递参数的方法

request.getRequestDispatcher("/test/forward.do?name="+name).forward(httpServletRequest, httpServletResponse);
ForwardController中获取参数
复制代码
@RestController
@RequestMapping("test")
public class ForwardController extends AbstractBaseController {
    
    @RequestMapping(value = "/forward.do", method = RequestMethod.POST)
    public LimitRspInfo alert(HttpServletRequest request, HttpServletResponse response) {

        String name = request.getParameter("name");
        ...
    }
}
相关文章
相关标签/搜索