精华内容
下载资源
问答
  • 转发与重定向的区别

    2016-01-07 20:24:21
    描述转发与重定向的区别,讲的比较详细,希望大家喜欢.
  • 请求转发与重定向的区别,并介绍请求转发与重定向 ** 一.请求转发与重定向的区别 1) 重定向对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个叫“浏览器”...

    请求转发与重定向的区别,并介绍请求转发与重定向

    请求转发与重定向的区别

    一.请求转发与重定向的区别
    1)

    重定向对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。

    由此可见,重定向的时候,“浏览器”一共发出了两封信和收到了两次回复,“浏览器”也知道他借到的钱出自李四之手。

    而请求转发方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。

    由此可见,转发的时候,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。

    2)重定向
    两次请求,两次响应
    重定向不携带数据
    重定向地址栏发生改变
    3)转发
    一次请求,一次响应
    转发需要携带数据
    转发地址栏不会发生变化
    4) 使用
    如果要保留请求域中的数据,使用转发,否则使用重定向。
    以后访问数据库,增删改使用重定向,查询使用转发。
    5)小结
    1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
    2、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;
    3、转发是服务器行为,重定向是客户端行为;
    4、转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
    5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

    在这里插入图片描述

    请求转发

    二.请求转发
    1)什么是请求转发
    浏览器访问Servlet1,Servlet1将参数处理得到结果,没有直接返回给浏览器,而是将结果带给Servlet2,由Servlet2再处理之后返回给浏览器
    在这里插入图片描述
    2 )代码实现

    request.getRequestDispatcher("/demo07").forward(request, response);
    

    在这里插入图片描述
    3)特点
    1.地址栏不发生变化,显示的是上一个页面的地址
    2.请求次数:只有1次请求
    3.请求域中数据不会丢失

    4).例子
    Servlet01

    @WebServlet("/demo01")
    public class Demo06Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //将"游戏本"添加到请求中,携带到下一个servlet
            //1 存数据
            request.setAttribute("name","电脑");
            //2 携带到下一个servlet,只能使用转发
      request.getRequestDispatcher("/demo07").forward(request, response);
        }
    }
    (这就是第一个Servlet01,通过请求转发发给下一个Servlet02)
    

    Serlvet02

    @WebServlet("/demo02")
    public class Demo07Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1 取数据
            String name = (String) request.getAttribute("name");
            //2 组装标签后,响应给浏览器
            response.setContentType("text/html;charset=utf-8");
    response.getWriter().println("<font color='red'>"+name+"</font>");
        }
    }
    

    重定向

    三.重定向
    1)什么是请求转发
    浏览器访问Servlet1,Servlet1不知道结果,但是Servlet1知道Servlet2知道结果,将Servlet2的地址返回给浏览器,浏览器根据Servlet1给的地址访问Servlet2,Servlet2将参数处理得到结果返回给浏览器

    在这里插入图片描述

    2 )代码实现

    response.sendRedirect(request.getContextPath()+"要跳转的页面")
    

    3 )特点
    两次请求,两次响应
    重定向不携带数据
    重定向地址栏发生改变

    4)例子
    Servlet01

    @WebServlet("/demo01")
    public class Demo06Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1 存数据
            request.setAttribute("name","电脑");
    response.sendRedirect(request.getContextPath()+"demo02")
        }
    }
    
    

    Servlet02

    @WebServlet("/demo02")
    public class Demo07Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    response.getWriter().println(request.getAttribute("name"));
        }
    }
    
    展开全文
  • 转发与重定向

    万次阅读 多人点赞 2018-07-27 15:03:47
    转发是服务器行为,重定向是客户端行为。转发耗时比重定向少。 转发——&gt;客户浏览器发送HTTP请求——&gt;web服务器接受请求——&gt;调用内部一个方法在容器内部完成请求处理和转发动作——&gt;...

    转发是服务器行为,重定向是客户端行为。转发耗时比重定向少。

    转发——>客户浏览器发送HTTP请求——>web服务器接受请求——>调用内部一个方法在容器内部完成请求处理和转发动作——>再将转发跳转到的那个网页资源返回给客户;  转发只能在同一个容器内完成 转发的时候浏览器地址是不会变的,在客户浏览器里只会显示第一次进入的那个网址或者路径,客户看不到这个过程,只是得到了想要的目标资源。转发行为浏览器只做了一次请求。(转发只能跳转一次)

    重定向——>客户浏览器发送HTTP请求——>web服务器接受请求后发送302状态码以及新的位置给客户浏览器——>客户浏览器发现是302响应,则自动再发送一个新的HTTP请求,请求指向新的地址(302:Found  临时移动,但资源只是临时被移动。即你访问网址A,但是网址A因为服务器端的拦截器或者其他后端代码处理的原因,会被重定向到网址B。)——>服务器根据此请求寻找资源发个客户;再客户浏览器中显示的是重定向之后的路径,客户可以看到地址的变化。重定向行为浏览器做了至少两次请求。(重定向可以跳转多次)

    从图解可以看出转发时客户端只发送了一次请求,而重定向时客户端需要发送至少两次请求。

    如生活实例(假如去办个证件):

    重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。 

    转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。

    一、转发:

    index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!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=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<form action="second" method="get">
    	<input type="submit" value="登陆 ">
    	</form>
    </body>
    </html>

    Second.java

    package com.xianyadong.demo;
    
    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("/second")
    public class Second extends HttpServlet{
    	private static final long serialVersionUID = 1L;
        
    	   
        public Second() {
            super();
          
        }
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
        	System.out.println("=====");
        	request.getRequestDispatcher("/welcome").forward(request, response);
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
        	doGet(request, response);
    
        }
    
     
    }

    Welcome.java

    package com.xianyadong.demo;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    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("/welcome")
    public class Welcome extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
       
        public Welcome() {
            super();
          
        }
    
    	
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setCharacterEncoding("utf-8");
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter writer = response.getWriter();
    		writer.println("<html>");
    		writer.println("<body>欢迎"+"</body>");
    		
    		
    		writer.println("</html>");
    	}
    
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	
    		doGet(request, response);
    	}
    
    }
    

    浏览器点击登录去访问Second.java 然后Second通过转发返回给浏览器Welcome.java的内容。

     

     

     

     

     

     

     

     

     

     

     

     

     

    从图可以看出网站地址只会显示second不会出现welcome。

    二、重定向

    index.java 还用上面原来的

    Second.java

    package com.kaoshi.chongdingxiang;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    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("/second")
    public class Second extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        
        public Second() {
            super();
          
        }
    
    	
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	
    	}
    
    	
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		response.sendRedirect("welcome");
    	}
    
    }

    Welcome.java

    package com.kaoshi.chongdingxiang;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    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("/welcome")
    public class Welcome extends HttpServlet {
    	private static final long serialVersionUID = 1L;
      
        public Welcome() {
            super();
            
        }
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setCharacterEncoding("utf-8");
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter writer = response.getWriter();
    		StringBuffer requestURL = request.getRequestURL();
    		writer.println(requestURL.toString());
    		writer.println("<br>");
    		int status = response.getStatus();
    		writer.println(status);
    		writer.println("<html>");
    		writer.println("<body>欢迎"+"</body>");
    		writer.println("</html>");
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		doGet(request, response);
    	}
    
    }

    从图片中网址那栏不难看出转发的后面是Second而重定义的后面则是Welcome。

    展开全文
  • 转发与重定向区别

    2015-09-14 16:59:28
    尽管HttpServletResponse.sendRedirect方法和RequestDispatcher.forward方法都可以让浏览器...下面是HttpServletResponse.sendRedirect方法实现的请求重定向与RequestDispatcher.forward方法实现的请求转发的总结比较
  • 主要介绍了java 转发重定向区别及实例代码的相关资料,需要的朋友可以参考下
  • 请求转发与重定向详解

    千次阅读 2018-06-08 00:07:03
    https://blog.csdn.net/Goskalrie/article/details/51217630(转载)转发和包含Servlet对象由Servlet容器创建,并且Servlet对象的service()方法也由容器调用。一个Servlet对象可否直接调用另一个Servlet对象的...

    https://blog.csdn.net/Goskalrie/article/details/51217630(转载)

    转发和包含

    Servlet对象由Servlet容器创建,并且Servlet对象的service()方法也由容器调用。一个Servlet对象可否直接调用另一个Servlet对象的service()方法呢?答案是否定的,因为一个Servlet对象无法获得另一个Servlet对象的引用。

    在旧版的Servlet API中,ServletContext接口中的getServlet(Stringname)方法能根据参数给定的名字返回相应的Servlet对象的引用。从Servlet API2.1开始,该方法被放弃。对于支持Servlet API2.1或者以上版本的Servlet容器,会使得ServletContext实现类的getServlet(String name)方法总是返回null。因此,一个Servlet对象无法再获得另一个Servlet对象的引用。

    Web应用在响应客户端的一个请求时,有可能响应过程很复杂,需要多个Web组件共同协作,才能生成响应结果。尽管一个Servlet对象无法直接调用另一个Servlet对象的service()方法,但Servlet规范为Web组件之间的协作提供了两种途径。

    ·  请求转发:Servlet(源组件)先对客户请求做一些预处理操作,然后把请求转发给其他Web组件(目标组件)来完成包括生成响应结果在内的后续操作。

    ·  包含:Servlet(源组件)把其他Web组件(目标组件)生成的响应结果包含到资自身的响应结果中。

    请求转发与包含具有以下共同特点:

    ·  源组件和目标组件处理的都是同一个客户请求,源组件和目标组件共享同一个ServletRequest对象和ServletResponse对象。

    ·  目标组件都可以为Servlet、JSP或HTML文档。

    ·  都依赖javax.servlet.RequestDispatcher接口。

    javax.servlet.RequestDispatcher接口表示请求分发器,它有两个方法。

    public void forward(ServletRequest request,ServletResponse response)

            throws ServletException, IOException;

    把请求转发给目标组件。


    public void include(ServletRequest request,ServletResponse response)

            throws ServletException, IOException;

    包含目标组件的响应结果。


    Servlet组件调用RequestDispatcher的forword()或include()方法时,都要把当前的ServletRequest对象和ServletResponse对象作为参数传给forward()或include()方法,这使得源组件和目标组件共享同一个ServletRequest对象和ServletResponse对象

    Servlet可通过两种方式得到ResquestDispatcher对象:

    调用ServletContext的getRequestDispatcher(Stringpath)方法,path参数指定目标组件的路径。

    调用ServletRequest的getRequestDispatcher(Stringpath)方法,path参数指定目标组件的路径。

    以上两种方式的区别在于,前者的path路径必须为绝对路径,而后者的path参数既可以为绝对路径,也可以为相对路径。所谓绝对路径,就是指以符号“/”开头的路径,“/”表示当前Web应用的URL入口。所谓相对路径,就是相对于当前源Servlet组件的路径,不以符号“/”开头。

    请求转发

    请求转发的处理流程:

    (1)      清空用于存放响应正文数据的缓冲区。

    (2)      如果目标组件为Servlet或JSP,就调用它们的service()方法,把该方法产生的响应结果发送到客户端;如果目标组件为文件系统中的静态HTML文档,就读取文档中的数据把它发送到客户端。

    请求转发特点:

    (1)            由于forword()方法先清空用于存放响应正文的缓冲区,因此Servlet源组件生成的响应结果不会被发送到客户端,只有目标组件生成的响应结果才会被发送到客户端。

    (2)            如果源组件在进行请求转发之前,已经提交了响应结果(例如调用ServletResponse的flushBuffer()方法,或者调用与ServletResponse关联的输出流的close()方法),那么forward()方法抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。

    表现:

    地址不会变,转发前对request对象的设置能够传递到转发后的Web组件。请求转发是一个链式的,中间无论转发过多少次始终是同一个请求对象。


    包含

    RequestDispatcher对象的include()方法的处理流程如下:

    (1)      如果目标组件为Servlet或JSP,就调用他们的相应的service()方法,把该方法产生的响应正文添加到源组件的响应结果中;如果目标组件为HTML文档,就直接把文档的内容添加到源组件的响应结果中。

    (2)      返回到源组件的服务方法中,继续执行后续代码块。

    包含与请求转发相比,包含有以下特点:

    (1)      源组件与被包含的目标组件的输出数据都会被添加到响应结果中。

    (2)      在目标组件中对响应状态码或者响应头所做的修改都会被忽略。

    重定向

    HTTP协议规定了一种重定向机制,重定向的运作流程如下:

    (1)      用户在浏览器端输入特定URL,请求访问服务器端的某个组件。

    (2)      服务器端的组件返回一个状态码为302的响应结果,该响应结果的含义为:

    让浏览器端再请求访问另一个Web组件,在响应结果中提供了另一个Web组件的URL。另一个Web组件有可能在同一个Web服务器上,也有可能不再同一个Web服务器上。

    (3)      当浏览器端接收到这种响应结果后,再立即自动请求访问另一个Web组件。

    (4)      浏览器端接收到另一个Web组件的响应结果。

    重定向使用的方法是sendRedirect(String location),该方法具有以下特点:

    (1)      Servlet源组件生成的响应结果不会被发送到客户端。response.sendRedirect(String location)方法一律返回状态码为302的响应结果。浏览器端接收到这种响应结果后,再立即请求房屋内重定向的目标Web组件,客户端最后接收到的目标Web组件的响应结果。

    (2)      如果源组件在进行重定向之前,已经提交了响应结果(例如调用ServletResponse的flushBuffer()方法,或者调用与ServletResponse关联的输出流的close()方法),那么sendRedirect()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。

    (3)      在Servlet源组件中调用response.sendRedirect()方法之后的代码块也会被执行。

    (4)      源组件和目标组件不共享同一个ServletRequest对象,因此不共享请求范围内的共享数据。

    (5)      对于response.sendRedirect(String location)方法中的参数location,如果以“/”开头,表示相对于当前服务器根路径的URL,如果以http://开头,表示一个完整的URL。

    (6)      目标组件不必是同一个服务器上的同一个Web应用中的组件,它可以是Internet上的任意一个有效的网页。


    访问Servlet容器内的其他Web应用

    在一个Servlet容器进程内可以同时运行多个Web应用,那么在这些Web应用之间可否进行通信呢?答案是肯定的。每个Web应用都有一个ServletContext大总管。对于Web应用A中的Servlet,只要得到了Web应用B的ServletContext对象,就能访问到Web应用B的各种资源。

    ServletContext接口中的getContext(Stringuripath)方法用于得到其他Web应用的ServletContext对象。参数uripath指定其他Web应用的URL入口。

    一个Web应用随意访问另一个Web应用的各种资源,可能会导致安全问题。因此,为了安全起见,多数Servlet容器实现可以让用户设置是否允许Web应用得到其他Web应用的ServletContext对象。在Tomcat中,<Context>元素的crossContext属性用于设置该选项:

    如果crossContext属性为false,那么<Context>元素对应的Web应用无法得到其他Web应用的ServletContext对象。当这个Web应用中的Servlet调用getContext(Stringuripath)方法时,该方法总是返回null。crossContext属性的值默认为false。

    如果crossContext属性为true,那么<Context>元素对应的Web应用可以得到其他Web应用的ServletContext对象。当这个Web应用中的Servlet调用getContext(String uripath)方法时,该方法返回参数uripath对应的其他Web应用的ServletContext对象。

    请求转发与重定向的区别

    示例(演示二者区别)

    [java] view plain copy
    1. public class MyServlet1 extends HttpServlet {  
    2.     private static final long serialVersionUID = 1L;  
    3.   
    4.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    5.         this.doPost(request, response);  
    6.     }  
    7.   
    8.     protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {  
    9.         req.setAttribute("username""Jack");  
    10.         PrintWriter out = res.getWriter();  
    11.         out.println("hello");  
    12. //      out.close();  
    13. //      res.flushBuffer();  
    14.         req.getRequestDispatcher("MyServlet2").forward(req, res);  
    15. //      res.sendRedirect("MyServlet2");  
    16. //      res.sendRedirect("http://blog.csdn.net/goskalrie");//ok  
    17. //      req.getRequestDispatcher("http://blog.csdn.net/goskalrie").forward(req, res);//HTTP Status 404 - /webdemo/http://blog.csdn.net/goskalrie  
    18.     }  
    19. }  

    [java] view plain copy
    1. public class MyServlet2 extends HttpServlet {  
    2.     private static final long serialVersionUID = 1L;  
    3.          
    4.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    5.         this.doPost(request, response);  
    6.     }  
    7.   
    8.     protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {  
    9.         res.setContentType("text/html;charset=utf-8");  
    10.         PrintWriter out = res.getWriter();  
    11.         out.println("<html><head><title>MyServlet2</title></head><body>"  
    12.                 + "<h1>" + req.getParameter("username")  
    13.                 + "</h1><br/>"  
    14.                 + "<h1>" + req.getAttribute("username")  
    15.                 + "</h1>"  
    16.                 + "</body></html>");  
    17.         out.close();  
    18.     }  
    19. }  

    [html] view plain copy
    1. <!DOCTYPE html>  
    2. <html>  
    3. <head>  
    4. <meta charset="UTF-8">  
    5. <title>登录</title>  
    6. </head>  
    7. <body>  
    8.     <form name = "loginForm" method="GET" action="MyServlet1">  
    9.         <table>  
    10.             <tr>  
    11.                 <td><div align="right">用户名:</div></td>  
    12.                 <td><input type="text" name="username"></td>  
    13.             </tr>  
    14.             <tr>  
    15.                 <td><input type="submit" name="submit" value="登录"></td>  
    16.                 <td><input type="reset" name="reset" value="重置"></td>  
    17.             </tr>  
    18.         </table>  
    19.     </form>  
    20. </body>  
    21. </html>  

    按照以下步骤进行实验

    (1)      启动服务器,访问登录login.html,填写用户名后登录,可以看到浏览器地址栏地址变为http://localhost:8080/webdemo/MyServlet2,页面中打印出两个null,并没有读取到原始的请求中username属性,也没有读取到在源组件中处理的request中setAttribute(“username” , “Jack”)的值。

    (2)      将MyServlet1中的res.sendRedirect("MyServlet2");代码注释掉,并将req.getRequestDispatcher("MyServlet2").forward(req,res);解开注释,重复步骤一,页面中打印出xiaoming和Jack两个名字,且地址栏的地址没有发生变化,只是在后面出现了请求的参数,但是实际的地址并没有改变。

    2.重定向

    重定向地址栏发生变化,在浏览器调试界面出现两个请求:


    其中第一个请求的响应中包含了重定向的地址,如下图的最后:


    在重定向方式中,请求是页面重新发送的,所以在请求中获取不到原始要提交的数据。即使在重定向前对原始请求做了处理,也是徒劳的。原因是请求对象和响应的对象的生命周期只存在于一次请求和响应中。客户端第一次发出请求,此时的请求为请求A,服务器接收到请求,生成对应的响应,然后程序遇到重定向语句,无论此时的请求和响应是什么,响应都会变成固定的:状态码为302,响应数据中包含重定向的组件地址。在浏览器响应之后,请求A和响应都消失了,然后浏览器自动的发出新的请求——请求B。在测试代码中含有两句代码以不同的方式进行请求外域名:

    //      res.sendRedirect("http://blog.csdn.net/goskalrie");//ok

    //      req.getRequestDispatcher("http://blog.csdn.net/goskalrie").forward(req,res);//HTTP Status 404 - /webdemo/http://blog.csdn.net/goskalrie

    正如注释显示的结果一样,使用重定向成功访问到,而使用请求转发则发生了异常。

    示例(跨域访问,系统维护提示)

    在实际的项目中可能有这样的情形:公司A和公司B共用一个服务器中的一个Web应用,但是各自有自己的数据库,公司A的员工A与公司B的员工B在登录该Web应用时,就需要从不同的数据库进行加载信息。假如,Web应用webdemo是共用的应用,包含了登录,信息展示等功能。Web应用webdemoA是公司A与数据库交互的Web应用。Web应用webdemoB是公司B与数据库交互的Web应用。上面的Web应用分布的模型应用应该说不少,比如,在某网站进行维护时,客户访问该网站,会收到“网站维护中”的页面信息提示,同样在下面的示例中将模拟该功能。按照分析所述,webdemo、webdemoA、webdemoB都在一个服务器中,使用重定向实现需求。

    webdemo中包含登录页面:
    [html] view plain copy
    1. <!DOCTYPE html>  
    2. <html>  
    3. <head>  
    4. <meta charset="UTF-8">  
    5. <title>登录</title>  
    6. </head>  
    7. <body>  
    8.     <form name = "loginForm" method="GET" action="MyServlet1">  
    9.         <table>  
    10.             <tr>  
    11.                 <td><div align="right">用户名:</div></td>  
    12.                 <td><input type="text" name="username"></td>  
    13.             </tr>  
    14.             <tr>  
    15.                 <td><div align="right">公司:</div></td>  
    16.                 <td><input type="text" name="company"></td>  
    17.             </tr>  
    18.             <tr>  
    19.                 <td><input type="submit" name="submit" value="登录"></td>  
    20.                 <td><input type="reset" name="reset" value="重置"></td>  
    21.             </tr>  
    22.         </table>  
    23.     </form>  
    24. </body>  
    25. </html>  

    登录页面同样请求MyServlet1,在MyServlet1中进行判断当前登录员工是A公司的还是B公司的,如果是公司A中的员工,重定向到webdemoA中的Web组件MyServlet2,如果是公司B中的员工,重定向到webdemoB中的Web组件MyServlet3,在webdemo中尝试连接webdemoA或webdemoB,连接失败则说明webdemoA或webdemoB在进行维护,无法访问,此时将请求转发至webdemo中的Web组件error.jsp。在实际的项目中不应该使用try-catch控制程序流程,在该实验中使用try-catch代替webservice,ajax等跨域请求的操作。实际的项目中,系统维护提示的实现方式有多种,这里仅是简单的模拟其中的一种情况。

    在webdemo中判断员工所属公司并控制重定向的MyServlet1:
    [java] view plain copy
    1. public class MyServlet1 extends HttpServlet {  
    2.     private static final long serialVersionUID = 1L;  
    3.   
    4.     protected void doGet(HttpServletRequest request,  
    5.             HttpServletResponse response) throws ServletException, IOException {  
    6.         this.doPost(request, response);  
    7.     }  
    8.   
    9.     protected void doPost(HttpServletRequest req, HttpServletResponse res)  
    10.             throws ServletException, IOException {  
    11.         String company = req.getParameter("company");  
    12.         String username = req.getParameter("username");  
    13.         URL urlA = new URL("http:localhost:8080/webdemoA");  
    14.         try {  
    15.             URLConnection conA = urlA.openConnection();  
    16.             conA.connect();  
    17.         } catch (Exception e) {  
    18.             req.getRequestDispatcher("error.jsp").forward(req, res);  
    19.         }  
    20.         if (company.equals("companyA")) {  
    21.             res.sendRedirect("/webdemoA/MyServlet2?username=" + username + "&company=" + company);  
    22.         } else if (company.equals("companyB")) {  
    23.             res.sendRedirect("/webdemoB/MyServlet3?username=" + username + "&company=" + company);  
    24.         }  
    25.     }  
    26. }  
    在webdemoA及webdemoB中作为重定向的目标组件,从对应公司的数据库中读取数据并进行验证,处理的Web组件MyServlet2、MyServlet3:
    [java] view plain copy
    1. public class MyServlet2 extends HttpServlet {  
    2.     private static final long serialVersionUID = 1L;  
    3.          
    4.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    5.         this.doPost(request, response);  
    6.     }  
    7.   
    8.     protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {  
    9.         res.setContentType("text/html;charset=utf-8");  
    10.         PrintWriter out = res.getWriter();  
    11.         out.println("<html><head><title>webdemoA/MyServlet2</title></head><body>"  
    12.                 + "<h1>" + req.getParameter("company")  
    13.                 + "</h1><br/>"  
    14.                 + "<h1>" + req.getParameter("username")  
    15.                 + "</h1>该值为后台从数据库加载数据后校验后的结果"  
    16.                 + "</body></html>");  
    17.         out.close();  
    18.     }  
    19. }  

    [java] view plain copy
    1. public class MyServlet3 extends HttpServlet {  
    2.     private static final long serialVersionUID = 1L;  
    3.   
    4.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    5.         this.doPost(request, response);  
    6.     }  
    7.   
    8.     protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {  
    9.         res.setContentType("text/html;charset=utf-8");  
    10.         PrintWriter out = res.getWriter();  
    11.         out.println("<html><head><title>webdemoB/MyServlet3</title></head><body>"  
    12.                 + "<h1>" + req.getParameter("company")  
    13.                 + "</h1><br/>"  
    14.                 + "<h1>" + req.getParameter("username")  
    15.                 + "</h1>该值为后台从数据库加载数据后校验后的结果"  
    16.                 + "</body></html>");  
    17.         out.close();  
    18.     }  
    19. }  
    以及提示服务器维护的error.jsp:
    [html] view plain copy
    1. <%@ page language="java" contentType="text/html; charset=utf-8"  
    2.     pageEncoding="utf-8"%>  
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
    4. <html>  
    5. <head>  
    6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    7. <title>error</title>  
    8. </head>  
    9. <body>  
    10. <h1><%=request.getParameter("username") %>,Sorry. . . 系统维护中。</h1>  
    11. </body>  
    12. </html>  

    该试验的代码下载[测试代码.7z],下载后解压将得到三个*.war文件,直接将这三个文件放到tomcat安装目录下的webapps文件夹中即可按下面的步骤进行实验:

    (1)将webdemo、webdemoA、webdemoB三个项目的打包文件放到tomcat安装目录下的webapps文件夹下,启动服务器访问localhost:8080/webdemo/login.html,在用户名中输入xiaoming,在公司中输入companyA(必须),点击登录,登录成功,观察地址栏,请求webdemoA/MyServlet2成功,地址栏显示 http://localhost:8080/webdemoA/MyServlet2?username=xiaoming&company=companyA,页面显示:

    (2)访问localhost:8080/webdemo/login.html,在用户名中输入zhanghua,在公司中输入companyB(必须),点击登录,登录成功,观察地址栏,请求webdemoB/MyServlet3成功,地址栏显示http://localhost:8080/webdemoB/MyServlet3?username=zhanghua&company=companyB,页面显示:

    (3)访问tomcat管理页面http://localhost:8080/manager/html,将webdemoA应用手动停止:

    (4)再次访问localhost:8080/webdemo/login.html,输入用户名和公司后登录,此时将会出现系统维护中的提示:


    在javax.servlet.RequestDispatcher接口中还有一个include()方法,此方法也可以将请求和响应进行转发,只不过如前面介绍中所述,include()方法向客户端返回的响应包含了请求链中所有的响应,如login.html向MyServlet1发出请求,includeMyservlet2,include MyServlet3,include hello.jsp。其中MyServlet1、MyServlet2、MyServlet3中简单的打印Servlet的名字,hello.jsp打印hello,页面显示结果:

    MyServlet1

    MyServlet2

    MyServlet3

    hello

    总结

    无论是请求转发还是重定向,亦或是包含,都是将请求交给其他Web组件进行处理,有些组件是控制流程的,有些组件是数据处理的,在程序设计时,为了让组件的功能专一,就可能在控制流程类型的Web组件中不对客户端产生响应,而是让数据处理类的Web组件进行响应客户请求,而在控制流程类Web组件中仅仅判断当前请求该由哪一个数据处理类的Web组件进行处理。还有些情况,如上面的示例代码,在当前应用中,需要访问其他Web应用的资源。总的来说,当一个Web组件不适合、不想或不能处理请求时,需要使用重定向或请求转发让其他Web组件来响应。




    展开全文
  • 请求转发: request.getRequestDispatcher().forward(); 重定向: response.sendRedirect(); 例如: 请求转发: request.getRequestDispatcher("/student_list.jsp").forward(request,response); 重定向: ...

    请求转发:

    request.getRequestDispatcher().forward();

    重定向:

    response.sendRedirect();

    例如:

    请求转发:

    request.getRequestDispatcher("/student_list.jsp").forward(request,response);

    重定向:

    response.sendRedirect(request.getContextPath + “/student_list.jsp”)

    在这里插入图片描述

    转发过程:客户端首先发送一个请求到服务器,服务器匹配Servlet,并指定执行。当这个Servlet执行完后,它要调用getRequestDispacther()方法,把请求转发给指定的Servlet_list.jsp,整个流程都是在服务端完成的,而且是在同一个请求里面完成的,因此Servlet和jsp共享同一个request,在Servlet里面放的所有东西,在student_list.jsp中都能取出来。因此,student_list.jsp能把结果getAttribute()出来,getAttribute()出来后执行完把结果返回给客户端,整个过程是一个请求,一个响应。

    重定向过程:客户端发送一个请求到服务器端,服务器匹配Servlet,这都和请求转发一样。Servlet处理完之后调用了sendRedirect()这个方法,这个方法是response方法。所以,当这个Servlet处理完后,看到response.sendRedirect()方法,立即向客户端返回个响应,响应行告诉客户端你必须再重新发送一个请求,去访问student_list.jsp,紧接着客户端收到这个请求后,立刻发出一个新的请求,去请求student_list.jsp,在这两个请求互不干扰、相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。因此,在sendRedirect()里面是两个请求,两个响应。

    Forward是在服务器端的跳转,就是客户端一个请求给服务器,服务器直接将请求相关参数的信息原封不动的传递到该服务器的其他jsp或Servlet去处理。而sendRedirect()是客户端的跳转,服务器会返回客户端一个响应报头和新的URL地址,原来的参数信息如果服务器没有特殊处理就不存在了,浏览器会访问新的URL所指向的Servlet或jsp,这可能不是原来服务器上的webService了。

    总结:

       1、转发是在服务器端完成的,重定向是在客户端发生的;
    
       2、转发的速度快,重定向速度慢;
    
       3、转发是同一次请求,重定向是两次请求;
    
       4、转发地址栏没有变化,重定向地址栏有变化;
    
       5、转发必须是在同一台服务器下完成,重定向可以在不同的服务器下完成。
    
    展开全文
  • 转发重定向是经常使用的两种页面跳转方法,但他们在原理实现和应用场景上都有很多的不同,总结如下: 1.语法不同 //转发 req.getRequestDispatcher("index.jsp").forward(req,resp); //重定向 resp....
  • 1、重定向的地址栏会变,而请求转发不会。 2、用户可以知道重定向使用那些资源,用户不知道请求转发内部发生什么。 3、请求转发只能是一次请求,用request对象共享数据,并且只能是当前服务器下的资源。 4、重定向两...
  • 请求转发 request.getRequestDispatcher().forward(); 是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这...
  • 请求转发与重定向详解代码,解读工作流程,详细内容在我的博客中有!
  • 典型的应用场景: forward: 访问 Servlet 处理业务逻辑,然后 forward 到 Java服务器端页面(jsp)显示处理结果,浏览器里 URL 不变2. redirect: 提交表单,处理成功后 redirect 到另一个 jsp页面,防止表单重复提交...
  • 96 - 用Flask实现转发与重定向

    千次阅读 2020-04-02 10:45:43
    转发与重定向
  • 请求转发与重定向

    千次阅读 2019-05-12 12:48:45
    1.请求转发 语法格式:request.getRequestDispatcher(URL地址).forward(request, response); 例子: 打开浏览器输入 http://127.0.0.1/demo/RequestServlet 结果为: 2.重定向 语法格式为:response....
  • USerLogin servlet 登录实例探究转发与重定向本质区别
  • 重定向与请求转发: 重定向(Redirect):客户端浏览器向Web应用服务器端发送一个请求,Web服务器端使用HttpServletResponse的sendRedirect()方法将结果(结果中头信息内HTTP状态码为302,Location响应报头域中...
  • 对JavaWeb中的转发与重定向的概念在HTTP数据包的基础上,进行明确的分析。
  • JSP:转发与重定向

    2021-05-24 11:20:34
    面试题:请求转发与重定向的区别? 1、请求转发是服务端跳转,重定向是客户端跳转 2、请求转发只有一次请求 从重定向村子啊两次请求 3、请求转发可以共享request作用域的数据 重定向不可以 4、请求转发地址栏不发生...
  • 主要介绍了Javaweb请求转发重定向实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • SpringBoot中处理的转发与重定向

    千次阅读 2020-02-02 08:56:09
    转发:一次请求,服务器内部调用另外的组件处理,request和response可以共用,有限制性,只能转发到本应用中的某些资源,页面或者controller请求 课可以...
  • servlet之转发与重定向的区别

    千次阅读 2017-09-05 16:11:07
    转发(服务器端跳转): 一次请求 request.getRequestDispatcher("new.jsp").forward(request, response); 重定向(客户端跳转): 两...转发重定向: 1.转发是在服务器端完成,因此称为服务器端跳转  重定向是在客户端完成
  • 调用HttpServletRequest对象的getRequestDispatcher()方法获取到RequsetDispatcher对象,通过RequestDispatcher对象的forward()方法可以完成请求转发功能。 request.getRequestDispatcher().forward(); 通过...
  • 转发与重定向的区别 转发是服务器行为,当客户端向服务器端发送一个请求时,服务器端带着请求中的url直接转发到另一个url当中,然后携带数据响应客户端。转发是一次请求,一次响应 重定向是客户端行为,当客户端向...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,780
精华内容 41,512
关键字:

转发与重定向