HttpServeltResponse接口中sendRedirect方法详解

转载 2018年04月16日 17:43:43

请求重定向

HTTP协议规定了一种重定向机制:

  • 用户在浏览器端输入特定的URL,请求访问服务器端的某个组件
  • 服务器端的组件返回一个状态代码为302的响应结果,该响应结果的含义为:让浏览器端再请求访问另一个Web组件。在响应的结果中提供了另一个Web组件的URL。另一个Web组件有可能在同一个Web服务器上,也有可能不在同一个Web服务器上
  • 当浏览器端接受到这种响应结果后,再立即自动请求另一个Web组件
  • 浏览器端接受到来自另一个Web组件的响应结果


在Java Servlet API中,HttpServeltResponse接口的sendRedirect(String location)方法用于重定向,而在ServletResponse接口中没有这个方法,因为重定向机制是由HTTP协议规定的。

[html] view plain copy
  1. javax.servlet.http  
  2. public interface HttpServletResponse  
  3. extends ServletResponse{  
  4.   
  5.     void    sendRedirect(String location)  
  6.     Sends a temporary redirect response to the client using the specified redirect location URL and clears the buffer  
  7. }  

  • 调用sendRedirect()方法会清空response buffer,因此Servlet源组件生成的响应结果不会被发送到客户端;客户端最后接受的目标组件的响应结果
  • 如果源组件在进行重定向之前,已经提交了响应结果(flush(),close()),那么sendRedirect()方法将会抛出IllegalStateException;为了避免异常,不应该在源组件中提交响应结果
  • 在源组件中,sendRedirect()调用后面的代码也会被执行
  • 源组件和目标组件不共享同一个ServletRequest对象,因此不共享请求范围内的共享数据
  • 对于response.sendRedirect(String location)方法中的参数location,如果不以“/”开头,表示相对于当前源组件的路径;如果以“/”开头,表示相对于当前服务器根路径的URL,如果以“http://”开头,表示一个完整的internet上的路径;
  • 目标组件不必是同一个服务器上的同一个Web应用的组件,它可以是Internet上的任意一个有效的网页



示例:

创建一个源组件,在其中将请求转发给另一个组件:

[html] view plain copy
  1. package com.gof.test.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import javax.servlet.ServletContext;  
  11.   
  12. public class RedirectSourceServlet extends HttpServlet {  
  13.     /**  
  14.      *   
  15.      */  
  16.     private static final long serialVersionUID = -729582654304035822L;  
  17.   
  18.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  19.             throws ServletException, IOException{  
  20.         PrintWriter out = resp.getWriter();  
  21.           
  22.         // try to get the parameter form request  
  23.         String username = req.getParameter("username");  
  24.         String message = null;  
  25.         if (username == null){  
  26.             message = "Please input username.";  
  27.         }else{  
  28.             message = "Hello, " + username;  
  29.         }  
  30.           
  31.         // try to add an attribute into the request  
  32.         req.setAttribute("msg", message);  
  33.           
  34.         out.println("Output from RedirectSourceServlet before redirecting.");  
  35.         // print to console  
  36.         System.out.println("Output from RedirectSourceServlet before redirecting.");  
  37.           
  38.         // redirect  
  39.         //resp.sendRedirect("/base-webapp/redirectdest?msg=" + message);  
  40.                 resp.sendRedirect("redirectdest?msg=" + message);  
  41.           
  42.         out.println("Output from RedirectSourceServlet after redirecting.");  
  43.         // print to console  
  44.         System.out.println("Output from RedirectSourceServlet after redirecting.");  
  45.     }  
  46. }  

目标组件为:

[html] view plain copy
  1. package com.gof.test.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import javax.servlet.ServletContext;  
  11.   
  12. public class RedirectDestinationServlet extends HttpServlet {  
  13.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  14.             throws ServletException, IOException{  
  15.         String message = (String)req.getAttribute("msg");  
  16.         System.out.println("The attribute added by Source Sevelt is " + message);  
  17.           
  18.         message = req.getParameter("msg");  
  19.         PrintWriter out = resp.getWriter();  
  20.         out.println(message);  
  21.         out.close();  
  22.     }  
  23. }  

在web.xml中注册:

[html] view plain copy
  1. <!-- Redirect request -->  
  2.   <!-- test url = http://localhost:8080/base-webapp/redirectsrc?username=New User -->  
  3.   <servlet>  
  4.      <servlet-name>redirectsrc</servlet-name>  
  5.      <servlet-class>com.gof.test.servlet.RedirectSourceServlet</servlet-class>  
  6.    </servlet>  
  7.    <servlet-mapping>  
  8.       <servlet-name>redirectsrc</servlet-name>  
  9.       <url-pattern>/redirectsrc</url-pattern>  
  10.    </servlet-mapping>  
  11.    <servlet>  
  12.      <servlet-name>redirectdest</servlet-name>  
  13.      <servlet-class>com.gof.test.servlet.RedirectDestinationServlet</servlet-class>  
  14.    </servlet>  
  15.    <servlet-mapping>  
  16.       <servlet-name>redirectdest</servlet-name>  
  17.       <url-pattern>/redirectdest</url-pattern>  
  18.    </servlet-mapping>  


在浏览器中请求如下URL:

[html] view plain copy
  1. http://localhost:8080/base-webapp/redirectsrc?username=New User  


可以看到浏览器显示的结果如下:



该请求由两部分组成,第一部分的response中的返回状态码为302,并包含重定向的URL。

同时,浏览器显式的URL变为:

[html] view plain copy
  1. http://localhost:8080/base-webapp/redirectdest?msg=Hello,%20New%20User  

在console中打印出的信息为:

[html] view plain copy
  1. Output from RedirectSourceServlet before redirecting.  
  2. Output from RedirectSourceServlet after redirecting.  
  3. The attribute added by Source Sevelt is null  


可以看到sendRedirect()方法后面的代码仍然会被执行;但是源组件中写入response中的内容不会被发送到客户端。

源组件和目标组件不共享请求范围内的数据,源组件向请求中存放的信息,在目标组件中无法获取该信息。


修改1:

在执行sendRedirect()方法之前,在源组件之前调用flush()方法;将会抛出IllegalStateException异常,同时浏览器会显示出源组件之前输出的内容。


修改2:

将sendRedirect()方法传入一个无效的servlet url,服务器端将返回页面未找到-404的错误提示。


修改3:

将sendRedirect()方法的参数修改为其他的internet网页,如“http://baidu.com”,请求访问源组件将指向这个网页。


转载自https://blog.csdn.net/robinjwong/article/details/39755509

探究java接口中的变量与方法

关于变量 java接口里的变量都是默认 pubic static final的 为啥? public 接口得能被所有对象调用 static 这个变量是属于接口本身,而不是实现了接口的对象的 具...
  • dlf123321
  • dlf123321
  • 2016-09-13 11:43:12
  • 1789

java接口里的变量和方法修饰符

java里面变量的修饰符默认  public static final,所以可以省略,而且必须显示初始化。 例如在接口里面定义的变量:public static final int a=1;   ...
  • sinat_35608637
  • sinat_35608637
  • 2017-06-30 13:54:20
  • 418

Servlet技术浅析(五)之-----ServletConfig接口和ServletContext接口

ServletConfig接口 简述          Servlet接口的init(ServletConfig config)方法有一个ServletConfig类型的参数。当Servlet容器初始...
  • u011159417
  • u011159417
  • 2017-01-06 10:43:00
  • 477

接口中的默认方法也是默认为public的吗??

。。。。
  • qq_39632912
  • qq_39632912
  • 2018-01-10 14:59:08
  • 210

接口里的default方法

我们都知道接口里的变量默认隐含类型是public static final,也是就是说是常量。而方法默认类型是public abstract,所以接口的方法都是抽象方法,但是事实真的是这样吗? ...
  • u014266077
  • u014266077
  • 2017-04-23 17:58:52
  • 2532

Java接口中的变量和方法默认的类型<转>

例子: 定义: interface MyService{        String name = "你真坏";        int getId(); } ---...
  • yongjian_luo
  • yongjian_luo
  • 2013-12-17 16:11:25
  • 1225

Java 8 接口里的默认方法特性

这篇文章我们将要探讨Java8中接口里的默认方法特性。Java8指出“默认方法使得新功能被添加到库中的接口里面,同时又能保证与这些接口老版本代码的二进制兼容性。” 这些年Java进化升级了很多,...
  • yin767833376
  • yin767833376
  • 2016-08-04 17:54:14
  • 1236

只实现接口中的其中一个方法

摘自:http://topic.csdn.net/u/20090627/21/d2956b19-3772-44bc-ad93-70aeaf9123dd.html?88471 面试官问: 有一个接口I,...
  • java_cxrs
  • java_cxrs
  • 2009-06-28 00:00:00
  • 1747

接口中的方法和成员变量

接口Interface 1. 接口中的成员变量默认都是public、static、final类型的,必须被显式初始化 2. 接口中的方法默认都是public、abstract类型的。 3. 接口...
  • liutong123987
  • liutong123987
  • 2017-12-27 10:55:34
  • 99

Java中接口中的方法定义规则

Java接口中的方法定义规则最近在做某个公司校招的笔试的时候,遇到了如下一个题:题目如下:(多选题)请选择以下接口定义正确的方法()A:public static void main (String[...
  • u010412719
  • u010412719
  • 2016-09-14 11:24:52
  • 8499
收藏助手
不良信息举报
您举报文章:HttpServeltResponse接口中sendRedirect方法详解
举报原因:
原因补充:

(最多只允许输入30个字)