zoukankan      html  css  js  c++  java
  • forward和sendRedirect的区别

    部分内容转自:http://blog.csdn.net/zhouysh/article/details/380364和http://blog.csdn.net/frank_jay/article/details/51243481

    1.RequestDispatcher.forward()

        是在服务器端起作用,当使用forward()时,Servletengine传递HTTP请求从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在b.jsp都可以获得,参数自动传递.

    但forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute("name",name)来传至下一个页面.

    重定向后浏览器地址栏URL不变.

         因为完成一个业务操作往往需要跨越多个步骤,每一步骤完成相应的处理后,转向到下一个步骤。比如,通常业务处理在Servlet中处理,处理的结果转向到一个 JSP页面进行显示。这样看起来类似于Servlet链的功能,但是还有一些区别。一个RequestDispatcher对象可以把请求发送到任意一个服务器资源,而不仅仅是另外一个Servlet。

    注意,只有在尚未向客户端输出响应时才可以调用forward()方法,如果页面缓存不为空,在重定向前将自动清除缓存。否则将抛出一个异常

    2.response.sendRedirect()

        是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,同时它可以重定向至不同的主机上,且在浏览器地址栏上会出现重定向页面的URL.

        HttpServletResponse接口定义了可用于转向的sendRedirect()方法。代码如下: 

    public void sendRedirect(java.lang.String location)throws java.io.IOException



    这个方法将响应定向到参数location指定的、新的URL。location可以是一个绝对的URL,如response.sendRedirect ("http://java.sun.com")也可以使用相对的URL。如果location以"/"开头,则容器认为相对于当前Web应用的根,否则,容器将解析为相对于当前请求的URL。这种重定向的方法,将导致客户端浏览器的请求URL跳转。从浏览器中的地址栏中可以看到新的URL地址,作用类似于上面设置HTTP响应头信息的实现 

    sendRedirect()方法是通过浏览器重定向的,所以第二个JSP页面中获得的request并非是前一个页面的request(两次请求生成了前后两个不同的 request对象了)。sendRedirect()是请求从定向,和超连接是一个意思,比如你在A页面中写一个request.setAtribute,sendRedirect到B页面,就是说服务器从A页面中给你一个response,然后你的浏览器再去request到B页面,由于有两次request和response,是不能在B页面取到request.setAtribute里的值,能从地址栏看到url的改变。

    request.getRequestDispatcher().forward(request,response)是请求分发器,比如你在A页面中写一个request.setAtribute,request.getRequestDispatcher().forward(request,response)到B页面,那就是说服务器给你的response是B页面的,并且只有一次request和response,所以是能在B页面取到request.setAtribute里的值,地址栏的url仍然是A页面的。

    所以通常情况下,setAttribute()方法都和RequestDispatcher.forward()都在一起使用

    看例子:

    一个简单的登录界面,这里是个登录的servlet:

    package com.library.service;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import com.library.dao.LoginDao;
    import com.library.po.Librarian;
    
    public class LoginServlet extends HttpServlet {
        
        private static final long serialVersionUID = 1L;
        LoginDao loginDao = new LoginDao();//引入持久层
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            super.doGet(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            String userName = req.getParameter("inputAccount");
            String password = req.getParameter("inputPassword");
            System.out.println("#############test:userName:"+userName+"  password:"+password);
            Librarian user = loginDao.loginSuccess(userName, password);
            
            
            
            
            if(user==null) {//不存在,登录失败
                Librarian userFail = new Librarian(userName, password);
                HttpSession session = req.getSession();
                req.setAttribute("theUser", userFail);
                session.setAttribute("theUser", userFail);
                System.out.println("Login Failed");
                req.getRequestDispatcher("/templates/loginFail.jsp").forward(req, resp);
            } else {
                HttpSession session = req.getSession();
                req.setAttribute("theUser", user);
                session.setAttribute("theUser", user);
                System.out.println("Login Success!");
                resp.sendRedirect("/TestWeb/templates/mainPage.jsp");
            }
        }
    }

    其中登录成功的页面是通过req.getRequestDispatcher("/templates/loginFail.jsp").forward(req, resp);来重定向的

    而登录失败页面是通过resp.sendRedirect("/TestWeb/templates/mainPage.jsp");来重定向的。

    分别在登录成功页面和登录失败页面用session和request来获得数据

    登录失败:

    <body>
        <h1>登录失败</h1>
        <%
            Librarian user = (Librarian)request.getAttribute("theUser");
            out.print("test in the dispatcher:<br>");
        %>
        userName:<%=user.getUserName() %><br>
        password:<%=user.getPassword() %><br><br>
        
        <%
            Librarian user2 = (Librarian)session.getAttribute("theUser");
            out.print("test in the session:<br>"); 
        %>
        userName:<%=user2.getUserName() %><br>
        password:<%=user2.getPassword() %><br>
        
    </body>

     发

    登录成功:

    <body>
    <h1>成功登录!</h1>
    
    
    <%
        //Librarian user = (Librarian)request.getAttribute("theUser");
        //out.print("test in the dispatcher:<br>");
    %> 
    
    <%-- 
    
        userName:<%=user.getUserName() %><br>
        password:<%=user.getPassword() %><br>
        age:<%=user.getAge() %><br>
    
     --%>
    
        
        
        
    
        
    <%
        Librarian user2 = (Librarian)session.getAttribute("theUser");
        out.print("test in the session:<br>"); 
    %>
        userName:<%=user2.getUserName() %><br>
        password:<%=user2.getPassword() %><br>
        age:<%=user2.getAge() %><br>
        position:<%=user2.getPosition() %><br><br>
        
    </body>

    结果是在登录失败页面两种方法都可以访问到user的信息,并且界面跳转后仍然是servlet的url(/login是form的action的url):

    而登录成功页面只能在session中访问的到,而且url变了:

    说明forward只有一次请求和回应,所以在重新定向的页面可以通过request访问的到之前request.setAttribute的数据,且url没变。

    而sendRediect跟超链接其实是一个意思,从A页面sendRedirect到B页面,就是说服务器从A页面中给你一个response,然后你的浏览器再去request到B页面,由于有两次request和response,是不能在B页面取到request.setAtribute里的值,能从地址栏看到url的改变。

  • 相关阅读:
    [BZOJ3884] 上帝与集合的正确用法
    [BZOJ3518] 点组计数
    [BZOJ3601] 一个人的数论
    [BZOJ3529] [Sdoi2014]数表
    原生js实现无缝滚动轮播图-点击页码即刻显示该页码的内容
    原生js实现无缝滚动轮播图
    vue封装tinymce富文本组件,图片上传回调方法
    vue-cli项目结合Element-ui基于cropper.js封装vue图片裁剪组件
    js实现多文件上传(二)-- 拖拽上传
    js实现多文件上传(一)-- 图片转base64回显
  • 原文地址:https://www.cnblogs.com/wangshen31/p/8335343.html
Copyright © 2011-2022 走看看