Servlet学习——请求转发与重定向的区别

请求转发与重定向

请求转发与重定向均是指的请求的跳转方式。用户提交请求需要访问服务端的资源 1, 而资源 1 又需要访问资源 2,那么由资源 1 向资源 2 的跳转,具有两种方式:请求转发与重 定向。 

(1) 请求转发 

请求转发是指,资源 1 在服务器内部,直接跳转到的资源 2,所以请求转发也称为服务 器内跳转。整个过程浏览器只发出一次请求,服务器只发出一次响应。所以,无论是资源 1 还是资源 2,整个过程中,只存在一次请求,即用户所提交的请求。所以,无论是资源 1 还 是资源 2,它们均可从这个请求中获取到用户提交请求时所携带的相关数据。 


(2) 重定向  

重定向是指,资源 1 需要访问资源 2,但并未在服务器内直接访问,而是由服务器自动 向浏览器发送一个响应,浏览器再自动提交一个新的请求,这个请求就是对资源 2 的请求。 对于资源 2 的访问,是先跳出了服务器,跳转到了客户端浏览器,再跳回到了服务器。所以 重定向又称为服务器外跳转。 整个过程中,浏览器共提交了两次请求,服务器共发送了两次响应。只不过,第一次响 应与第二次请求,对于用户来说是透明的,是感知不到的。用户认为,自己只提交了一次请 求,且只收到了一次响应。 这样的话,就出现了一个问题:资源 2 中是无法获取到用户提交请求中的数据的。它只 能获取到第二次请求中所携带的数据。 

(3) 请求转发案例

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="login" method="post">
		姓名:<input type="text" name="uname"/><br/>
		坐标:<input type="text" name="uplace"/><br/>
		<input type="submit" value="提交">
	</form>
</body>
</html>

LoginServlet.java

package com.orbit.servlet;

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("/login")
public class LoginServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		//获取请求参数值
		String name = request.getParameter("uname");
		String place = request.getParameter("uplace");
		
		//将请求参数值封装到域属性中
		request.setAttribute("loginName",name);
		request.setAttribute("loginPlace",place);
		
		//请求转发
		request.getRequestDispatcher("second").forward(request, response);		
	}
}

SecondServlet.java

package com.orbit.servlet;

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 SecondServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置响应体的内容类型
		response.setContentType("text/html;charset=ISO-8859-1");
		//setCharacterEncoding的作用其实就是修改setContentType的charset值
		response.setCharacterEncoding("UTF-8");
		
		//该页面也可以获取该请求的参数值
		String name = request.getParameter("uname");
		String place = request.getParameter("uplace");
		
		//获取域属性值
		String secondName = (String) request.getAttribute("loginName");
		String secondPlace = (String) request.getAttribute("loginPlace");
		
		//标准输出流
		PrintWriter out = response.getWriter();
		out.print("---请求的参数值---" + "<br/>" + "name = " + name + "<br/>" + "place = " + place + "<br/>");
		out.print("---请求的域属性---" + "<br/>" + "name = " + secondName + "<br/>" + "place = " + secondPlace);	
	}
}

输出结果

(4) 重定向案例

index.html(同上)

Loginservlet.java

package com.orbit.servlet;

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("/login")
public class LoginServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		request.setCharacterEncoding("UTF-8");
		
		//获取请求参数值
		String name = request.getParameter("uname");
		String place = request.getParameter("uplace");
		//将请求参数值封装到域属性
		request.setAttribute("loginName",name);
		request.setAttribute("loginPlace",place);
		
		//请求转发
		response.sendRedirect("second");	
	}
}

SecondServlet.java(同上)

输出结果:

 

(5) 重定向的数据传递

重定向时是无法将用户提交请求中的数据传递到重定向的资源的。若要向重定向的资源 中传递数据,则需要在重定向的请求地址后携带请求参数。  

携带请求参数的形式为:  请求路径?参数名=值&参数名=值&„„ 

index.html

secondServlet.java

LoginServlet.java

package com.orbit.servlet;

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("/login")
public class LoginServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		//获取请求参数值
		String name = request.getParameter("uname");
		name = new String(name.getBytes("UTF-8"),"ISO8859-1");
		String place = request.getParameter("uplace");
		place = new String(place.getBytes("UTF-8"),"ISO8859-1");
		//将请求参数值封装到域属性
		request.setAttribute("loginName",name);
		request.setAttribute("loginPlace",place);
		
		//请求转发
		response.sendRedirect("second?loginName=" + name + "&loginPlace=" + place);
	}
}

输出结果:

 

(6) 使用重定向到其他的应用(项目)

redirect-1/FirstServlet.java

package orbit;

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("/first")
public class FirstServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//重定向到另一个应用名为redirect-2的second页面
		response.sendRedirect("/redirect-2/second");
	}
}

redirect-1/SecondServlet.java

package orbit;

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 SecondServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.print("this is SecondServlet");
	}

}

输出结果:

 

(7) 请求转发与重定向的区别

请求转发重定向
A、浏览器只发出一次请求,收到一次响应A、浏览器发出两次请求,接收到两次响应
 
B、请求所转发到的资源中可以直接获取到请求中所携带的数据B、重定向到的资源不能直接获取到用户提交请求中所携带的数据
C、浏览器地址栏显示的为用户所提交的请求路径C、浏览器地址栏显示的为重定向的请求路径,而非用户提交请求的路径。也正因为如此, 重定向的一个很重要作用是:防止表单重复提交 (即便刷新地址栏也不会提交到用户提交请求的路径)
D、只能跳转到当前应用的资源中 D、重定向不仅可以跳转到当前应用的其它资源,也可以跳转到到其它应用中资源 

 

(8) 请求转发与重定向使用的情况

(1)若需要跳转到其它应用,则使用重定向。

(2)若是处理表单数据的 Servlet 要跳转到其它 Servlet,则需要选择重定向。为了防止表单重复提交。

(3)若对某一请求进行处理的 Servlet 的执行需要消耗大量的服务器资源(CPU、内存),此 时这个 Servlet 执行完毕后,也需要重定向。 (也是为了防止表单重复提交)

(4)其它情况,一般使用请求转发

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值