SpringMVC 控制器的响应(转发、重定向)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44296929/article/details/102523371

一、常见的响应方式:

1、重定向:
1)什么是重定向?
服务器通知浏览器向某个地址发送请求。

注:服务器可以发送302状态码和Location消息头
(该消息头的值是一个地址,一般称之为重定向地址)给浏览器,
浏览器收到之后,会立即向重定向地址发送请求。

在这里插入图片描述
2)如何重定向?
response.sendRedirect(String url);

注:url是重定向地址。
容器在重定向之前,会清空response对象上存放的所有数据。

3)特点:
a.重定向之后,浏览器地址栏的地址会发生改变。
b.重定向的地址是任意的。


2、转发: 1)什么是转发? 一个web组件将未完成的处理交给另外一个web组件继续做。
注:web组件: jsp或者servlet的统称。
通常是一个servlet获得数据,然后转发给一个jsp来展现。

在这里插入图片描述
2)如何转发?
step1.绑订数据到request对象上。

request.setAttribute(String name,Object obj);
注:
	a. name通常称之为绑订名,obj称之为绑订值。
	b. 该方法内部的实现:就是以name作为key,以
		obj作为value,调用Map.put方法。
	c.  Object request.getAttribute(String 	name);

step2.获得转发器。

RequestDispatcher rd = 
		request.getRequestDispatcher(Sting uri);
注:
	a.uri:转发的目的地,通常是一个jsp。
	b.RequestDispatcher是一个接口,该方法会返回	一个符合该接口的对象,这个对象一般我们称	之为转发器。	
	c.转发的本质是一个web组件通知容器去调用另外一个web组件,可以将转发器理解为web组件通知容器的媒介。

step3.转发

	rd.forward(request,response);

3)特点:

a.转发之后,浏览器地址栏的地址不变。
b.转发的目的地有限制,要求属于同一个web应用。

3、比较转发与重定向:
a. 地址栏地址有无变化:
转发之后,浏览器地址栏地址不变;重定向之后,浏览器
地址栏地址会发生改变。

b. 目的地有无限制:
转发有限制,重定向没有任何限制。

c. 能否共享request对象和response对象:
转发可以,重定向不行。

注:
	容器收到请求之后,会立即创建request对象和
	response对象。当响应发送完毕,容器会立即销毁
	这两个对象。也就是说,request对象和response
	对象的生存时间是一次请求与响应期间存在。
	重定向是两次请求。

d. 一件事是否完成
转发是一件事未做完,让另外一个web组件继续做;
而重定向是一件事已经完成,再做另外一件独立的事件。

3.1. 【不推荐】将转发的数据封装在HttpServletRequest对象中:
可以为处理请求的方法添加HttpServletRequest request参数,当需要转发数据时,将数据封装在request中即可,后续也不需要显式的执行转发,在SpringMVC的控制器中,默认的响应方式就是转发。

@RequestMapping("handle_reg.do")
public String handleReg(User user,
		HttpServletRequest request) {
	// 假定输入的用户名已经被占用
	// 提示:您输入的用户名XXX已经被占用
	request.setAttribute("msg", 
		"您输入的用户名" + user.getUsername() + "已经被占用!");
	// 返回视图名,也可以理解为文件的文件名
	return "error"; // 页面:/WEB-INF/error.jsp
} 

3.2. 【不推荐】使用ModelAndView:
可以将处理请求的方法的返回值设置为ModelAndView类型,该类型的常用构造方法有:

ModelAndView()
ModelAndView(String viewName)
ModelAndView(String viewName, Map<String, ?> model)

当需要转发数据时,可以使用以上3种中的最后一种:

@RequestMapping("handle_reg.do")
public ModelAndView handleReg(String username) {
	String viewName = "error";
	Map<String, Object> model
		= new HashMap<String, Object>();
	model.put("msg", 
			"[2] 您输入的用户名" + username + "已经被占用!");
	ModelAndView mav
		= new ModelAndView(viewName, model);
	return mav;
}

由于这种方式使用相对比较复杂,所以,一般不推荐使用这种做法!

3.3. 【推荐】使用ModelMap封装需要转发的数据:
使用ModelMap的流程与使用HttpServletRequest完全相同,即:方法的返回值依然使用String类型,在方法中声明该参数,然后在方法体中直接封装数据,最后,返回视图名:

@RequestMapping("handle_reg.do")
public String handleReg(String username,
		ModelMap modelMap) {
	modelMap.addAttribute("msg", 
		"[3] 您输入的用户名" + username + "已经被占用!");
	return "error";
}

3.4. 小结:
在SpringMVC中,转发数据共有3种做法,第1种使用HttpServletRequest的做法简单直接,但是,并不推荐这样处理,主要是因为框架已经帮我们处理了request需要执行的任务,而我们在编写代码时应该尽量不干预框架的处理过程,第2种使用ModelAndView,是框架的核心处理方式,但是,因为使用方式过于麻烦,所以,也不推荐这样使用,第3种使用ModelMap,使用简洁,推荐使用。

3.5. 附:重定向:
在SpringMVC中,当需要重定向时,首先,应该保证处理请求的方法的返回值是String类型(与转发一样),然后,返回值使用redirect:作为前缀即可,例如:

@RequestMapping("handle_reg.do")
	public String handleReg() {
		// 假设注册成功,需要登录
		return "redirect:login.do";
	}

需要注意的是:在redirect:右侧的不是视图名,而是重定向的目标的路径,可以是绝对路径,也可以是相对路径。

当处理的请求的返回值类型是String时,如果返回值使用redirect:作为前缀,是重定向,否则,是转发!

二、常见的响应码:

被服务器接收到的每个请求,在最终响应时,服务器端都会给出一个响应码,例如200404等。通常:

  • 2xx:正确的响应,例如200206等……
  • 3xx:重定向,例如302301等……
  • 4xx:请求错误,例如请求的资源不存在,或者请求类型错误、或者请求参数错误等等,例如400404405406等……
  • 5xx:服务器内部错误,通常可能是出现某种异常,例如500等……

猜你喜欢

转载自blog.csdn.net/weixin_44296929/article/details/102523371