在上次的小案例中用到了转发的技术,今天来仔细聊聊转发和重定向的问题,以及一些小知识的汇总。

一、转发

1、转发的概念

转发主要是将浏览器的请求交给另外一个servlet或jsp来处理,借助request对象完成,在服务器内部跳转,浏览器的地址并不发生改变,并且浏览器并不知道服务器内部发生了跳转,整个过程只会发生一次请求,转发的调用者和被调用者都可以共享request对象和response对象。

2、使用方法

因为是将数据交到另外一个servlet或jsp来处理请求,所以第一步是将需要处理的数据绑定到request对象上,可以使用request.setAttribute(String name, Object obj)方法,其中name是绑定名,obj是绑定值;也可以使用request.getSession().setAttribute(String name, Object obj)方法,绑定到session对象上。

第二步是获取转发器,也就是完成转发这件事需要用到的工具。

RequestDispatcher rd = request.getRequestDispatcher(String url);

url参数是转发的目标地址,可以是servlet,也可以是一个jsp页面,可以使用相对路径,也可以使用绝对路径。

第三步是调用转发器的方法来转发。

rd.forward(request,response);

当然,如果熟练后,可以将第二步和第三步合并为一步。

request.getRequestDispatcher(String url).forward(request, response);

3、转发的优缺点

转发的优点一是安全性高,在内部发生跳转,浏览器地址不变;二是节省资源,转发只需要一次请求,就可以访问至少两个servlet或jsp页面。在实际开发中,转发用到的较多。

转发的缺点是只能在同一web应用内使用,不能转发到外部的url地址。

二、重定向

1、重定向的概念

重定向是指服务器通知浏览器向一个新的地址发送请求,由response对象完成,可以重定向到新的servlet(服务器内部),也可以重定向到外部url(外部应用),浏览器地址发生改变,浏览器知道发生了跳转,整个过程会产生两次请求,重定向的调用者和被调用者不能共享request对象和response对象。

2、使用方法

response.sendRedirect(String url);

url是重定向的地址,可以是绝对路径,也可以是相对路径。

3、重定向的优缺点

重定向的优点是不限制应用范围,可以重定向到服务器内部其他资源,也可以是外部的应用。

重定向的缺点是耗费请求资源,重定向整个过程发生了两次的请求,一个是资源消耗上比转发大,效率也比转发低;另外,因为浏览器的地址发生了变化,相对转发来讲,安全性没有转发高。

三、路径问题

不管是使用转发还是重定向,都会涉及到路径的问题,路径分为相对路径、绝对路径。

绝对路径是指以"/"开头的路径信息。相对路径是指不以"/"开头的路径信息。

在项目中如果要使用绝对路径,重定向的路径是从应用名(上下文)开始,因为重定向时,服务器不知道这个请求是否在应用内部还是外部,所以需要加上应用名;转发时的路径是从应用名之后开始,转发是发生在服务器内部,在同一应用下,可以不用写应用名。

为了避免直接将应用名写在地址里面,可以使用request.getContextPath()方法来替代。

四、POST请求和GET请求

在前几次的小例子中,会经常看见jsp页面写post请求和get请求,在后台处理请求的doPost和doGet方法,下面对post请求和get请求来做下说明。

1、get请求

浏览器在下列三种情况出现时,会发送get请求,一是直接输入某个地址,二是点击链接,三是表单默认的提交方式。

get请求会将请求参数添加到请求资源路径的后面,是在get请求的url中发送的,url中只能存放2k左右的数据,并且请求参数会显示在浏览器地址栏,安全性较低,get请求会被缓存,会被保留在浏览器历史记录中,get请求只应用于取回数据。

2、post请求

设置表单的method属性值为post,浏览器会发送post请求。

post请求会将请求参数放在http消息主体中发送,可以提交大量数据,不会显示在浏览器地址栏,相对安全,但是对于敏感数据需要进行手动加密处理,post请求不会被缓存,也不会被保留在浏览器历史记录中。

五、验证转发与重定向,分别使用相对路径、绝对路径

第一步,新建一个Maven项目,建好两个Servlet类,写好两个jsp页面

package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 测试转发和重定向,分别使用相对路径、绝对路径
* @author 小川94
* @date 2018年6月10日
*/
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L; public FirstServlet() {
super();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("FirstServlet--->>> 进入doGet方法,交由doPost方法处理...");
doPost(request, response);
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("FirstServlet--->>> 执行POST请求...");
// 转发到second.jsp,使用绝对路径(不需要带应用名)
//request.getRequestDispatcher("/second/second.jsp").forward(request, response); // 转发到second.jsp,使用相对路径(不需要带应用名)
//request.getRequestDispatcher("second/second.jsp").forward(request, response); // 重定向到second.jsp,使用绝对路径(需要带应用名),推荐使用第二种写法
//response.sendRedirect("/servlet_day04/second/second.jsp");
//response.sendRedirect(request.getContextPath()+"/second/second.jsp"); // 重定向到second.jsp,使用相对路径(不需要带应用名)
//response.sendRedirect("second/second.jsp"); // 转发到SecondServlet,使用绝对路径(不需要带应用名)
//request.getRequestDispatcher("/SecondServlet").forward(request, response); // 转发到SecondServlet,使用相对路径(不需要带应用名)
//request.getRequestDispatcher("SecondServlet").forward(request, response); // 重定向到SecondServlet,使用绝对路径(需要带应用名),推荐使用第二种写法
//response.sendRedirect("/servlet_day04/SecondServlet");
//response.sendRedirect(request.getContextPath()+"/SecondServlet"); // 重定向到SecondServlet,使用相对路径(不需要带应用名)
response.sendRedirect("SecondServlet");
} }
package servlet;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class SecondServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public SecondServlet() {
super();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("SecondServlet--->>> 进入doGet方法,交由doPost方法处理...");
doPost(request, response);
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("SecondServlet--->>> 执行POST请求...");
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.println("<h1>这是SecondServlet中的响应数据</h1>");
pw.flush();
pw.close();
} }
<%@ 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>第一个jsp页面</title>
</head>
<body> <h1>这是第一个jsp页面</h1>
<hr>
<!-- ../表示根目录 -->
<a href="../FirstServlet">这是第一个GET请求</a>
<br/>
<!-- request.getContextPath()方法获取的是应用名 -->
<a href="<%=request.getContextPath() %>/FirstServlet">这是第二个GET请求</a>
</body>
</html>
<%@ 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>第二个jsp页面</title>
</head>
<body> <h1>这是第二个jsp页面</h1>
<hr> </body>
</html>

整个项目的目录结构如下图

第二步,分别使用相对路径和绝对路径测试转发和重定向

相对路径和绝对路径都是针对部署在Tomcat上文件的位置,不是工程目录结构,first文件夹和second文件夹下存放的是jsp页面,web-inf文件夹下存放的是编译的servlet的class文件。测试完你会发现使用相对路径是最省事的,但是如果你对相对路径不熟悉,那还是写绝对路径吧,好把控一些。

文章首发于我的个人公众号:悦乐书。喜欢分享一路上听过的歌,看过的电影,读过的书,敲过的代码,深夜的沉思。期待你的关注!

公众号后台输入关键字“Java学习电子书”,即可获得12本Java学习相关的电子书资源,如果经济能力允许,还请支持图书作者的纸质正版书籍,创作不易。

Servlet(四):转发与重定向、路径问题的更多相关文章

  1. Servlet中转发和重定向的路径问题【转】

    转发和重定向的路径问题 Servlet中有两种方式获得转发对象(RequestDispatcher):一种是通过HttpServletRequest的getRequestDispatcher()方法获 ...

  2. servlet的转发与重定向

    转发和重定向都能让浏览器获得另外一个URL所指向的资源,但两者的内部运行机制有着很大的区别. 1.转发:有两种方式获得转发对象(RequestDispatcher):一种是通过HttpServletR ...

  3. servlet请求转发于重定向

    请求的转发与重定向是Servlet控制页面跳转的主要方法,在Web应用中使用非常广泛. 一. 请求的转发 Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部" ...

  4. Servlet中转发和重定向的区别

    Servlet中页面的跳转有两种方式:转发和重定向. 1.转发和重定向的区别 ①转发是服务器行为,重定向是客户端行为. ②转发是浏览器发生了一次请求,重定向至少是两次请求. ③转发地址栏中的url不会 ...

  5. servlet之转发与重定向的区别

    转发(服务器端跳转):  一次请求 <jsp:forward> request.getRequestDispatcher("new.jsp").forward(requ ...

  6. Servlet中转发和重定向的路径问题以及表单提交路径问题

    一.请求转发与响应重定向的种类 有两种方式获得Servlet转发对象(RequestDispatcher):一种是通过HttpServletRequest的getRequestDispatcher() ...

  7. Servlet & JSP - 转发与重定向的区别

    本文转载自:http://blog.csdn.net/kobejayandy/article/details/13762043 转发 转发的原理,可以通过下图展示: 浏览器的请求发送给组件 1,组件 ...

  8. [Java][Web] Servlet中转发和重定向比较

    Servlet中页面跳转的两种方式 请求转发 使用requestDispatcher对象 request.getRequestDispatcher("path").forward( ...

  9. servlet请求转发与重定向的差别------用生活实例来形象说明两者的差别

    1,请求重定向:client行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保留,地址栏的URL地址会改变. 2,请求转发:server行为,req ...

  10. Servlet转发和重定向的区别

    附上视频教学的一张图: 区别: 1.转发产生一次请求,一次响应: 重定向产生2次请求 两次响应 2.转发客户端不可见的: 重定向客户端是可以察觉的. 3.转发时候url不变: 重定向URL会改变 案例 ...

随机推荐

  1. [转]OmniLayer / omnicore API 中文版

    本文转自:https://www.codetd.com/article/1692438 JSON-RPC API Omni Core是Bitcoin Core的一个分支,其Omni协议功能支持作为顶层 ...

  2. 第一册:lesson fifty five。

    原文: The Sawyer family. The Sawyers live at 87 King street. In the morning Mr.Sawyer goes to work and ...

  3. SQL Server导入导出不丢主键和视图的方法

    SQL Server导入导出 SQL Server 导入导出 工具/原料 使用Microsoft SQL Server Management Studio 导入导出数据. 直接使用Microsoft  ...

  4. mybatis笔记02

    目录 0. 文章目录 1. Mybatis映射文件 1.1 输入映射 1.2 输出映射 1.3 resultMap 2. 动态SQL 2.1 if和where 2.2 foreach循环 2.3 sq ...

  5. 学习HttpClient,从两个小例子开始

    前言 HTTP(Hyper-Text Transfer Protocol,超文本传输协议)在如今的互联网也许是最重要的协议,我们每天做的很多事情都与之有关,比如,网上购物.刷博客.看新闻等.偶尔你的上 ...

  6. Golang 正则表达式Regex相关资料整理

    Golang 支持的正在表达式是 https://github.com/google/re2/wiki/Syntax 注意这里提示 NOT SUPPORTED的。 工具 一些测试正则表达式的工具 推荐 ...

  7. 1.写页面 2.css的继承属性有哪些 3.margin对布局的影响

    1. sparent 透明的 2. placeholder 提示语 写页面 1.搞清结构层次 2. 保证模块化 让它们之间不能收到影响. (1) 元素性质 (2)标准流 浮动带来的脱离文档流撑不起父级 ...

  8. 怎么打开在.bashrc文件以及设置颜色

    打开/etc/bashrc,加入如下一行:   alias ls="ls --color"   下次启动bash时就可以像在Slackware里那样显示彩色的目录列表了,其中不同颜 ...

  9. 2018-11-13 中文代码示例之Programming in Scala学习笔记第二三章

    由于拷贝后文档格式有变, 仅摘几段如下. 完整而且代码带语法高亮的源版在: program-in-chinese/Programming_in_Scala_study_notes_zh 前言: 本书已 ...

  10. web框架的本质

    一 web框架的本质及自定义web框架 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响 ...