一、常见的响应方式:
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:作为前缀,是重定向,否则,是转发!
二、常见的响应码:
被服务器接收到的每个请求,在最终响应时,服务器端都会给出一个响应码,例如200
、404
等。通常:
- 2xx:正确的响应,例如
200
、206
等…… - 3xx:重定向,例如
302
、301
等…… - 4xx:请求错误,例如请求的资源不存在,或者请求类型错误、或者请求参数错误等等,例如
400
、404
、405
、406
等…… - 5xx:服务器内部错误,通常可能是出现某种异常,例如
500
等……