SpringMVC的执行流程
1. 向服务器发送Http请求,请求被前端控制器DispatcherServlet捕获。
2. DispatcherServlet根据<servlet-name>中的配置对请求的URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得Handler配置的所有相关的对象(包括Handler对象及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式进行返回。
3. DispatcherServlet根据获的Handler,选择一个适合的HandlerAdapter。
4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等。
数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5. Handler(Controller)执行完成后,向DispatcherServlet返回一个ModeAndView对象。
6. 根据返回的ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet。
7. ViewResolver 结合Model和View,来渲染视图
8. 视图负责将渲染的结果返回客户端。
常用注解
@RequestMapping
该注解可以在方法上也可以在类上,但意义是不同的。value 属性值常以“/”开始。@RequestMapping 的 value 属性用于定义所匹配请求的 URI。一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URI 是不同的。这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的value 属性中。但若这些请求具有相同的 URI 部分,则这些相同的 URI部分可以被抽取到注解在类之上的@RequestMapping 的 value 属性中。此时的这个 URI 表示模块(相当于包)的名称。URI 的请求是相对于 Web 的根目录。换个角度说,要访问处理器的指定方法,必须要在方法指定 URI 之前加上处理器类前定义的模块名称。
/*抽取前*/
@Controller
public class Hello{
@RequestMapping("/zar/no")
public String hello01(){
return "main";
}
@RequestMapping("/zar/yes")
public String hello01(){
return "main";
}
}
/*抽取后*/
@Controller
@RequestMapping("/zar")
public class Hello{
@RequestMapping("/no")
public String hello01(){
return "main";
}
@RequestMapping("/yes")
public String hello01(){
return "main";
}
}
@RequestMapping(value="/hello",method=?)
?为RequestMethod枚举中的常量,可选取GET POST ,对Http请求进行限制。
@PathVariable(动态占位符提交,仅限于超链接)
可以将URL的值作为参数进行提取
@RequestParam(适用于请求参数名称与形参名称不一致)
4种跳转方式
默认的跳转是请求转发,直接跳转到jsp页面展示,还可以使用框架提供的关键字redirect:,进行一个重定向操作,包括重定向页面和重定向action,使用框架提供的关键字forward:,进行服务器内部转发操作,包括转发页面和转发action。当使用redirect:和forward:关键字时,视图解析器中前缀后缀的拼接就无效了。
<a href="${pageContext.request.contextPath}/one.action">请求转发页面(默认)</a><br>
<a href="${pageContext.request.contextPath}/two.action">请求转发action</a><br>
<a href="${pageContext.request.contextPath}/three.action">重定向页面</a><br>
<a href="${pageContext.request.contextPath}/four.action">重定向action</a><br>
@Controller
public class JumpAction {
@RequestMapping("/one")
public String one(){
System.out.println("请求转发页面(默认)");
//以前的访问方式
//request.getRequestDispatcher("/admin/main.jsp").forward(request,response);
//观察地址栏的变化: http://localhost:8080/one.action
//return "main"; //默认的访问方式是自动拼接前缀和后缀进行跳转
return "forward:/fore/user.jsp";//只要使用了forward:就可以屏蔽前缀和后缀的拼接,自己手工构建返回的全部路径+.jsp
}
@RequestMapping("/two")
public String two(){
System.out.println("请求转发action");
//观察地址栏的变化: http://localhost:8080/two.action
return "forward:/other.action"; //不使用forward:,就会是这样的路径 /admin/other.action/.jsp
}
@RequestMapping("/three")
public String three(){
System.out.println("重定向页面");
//观察地址栏的变化 http://localhost:8080/admin/main.jsp
return "redirect:/admin/main.jsp";//只要使用了redirect:就可以屏蔽前缀和后缀的拼接
}
@RequestMapping("/four")
public String four(){
System.out.println("重定向action");
//观察地址栏的变化 http://localhost:8080/other.action
return "redirect:/other.action";//只要使用了redirect:就可以屏蔽前缀和后缀的拼接
}
}
默认支持的参数类型(写在方法参数上就可以使用)
1. HttpServletRequest
2. HttpServletResponse
3. HttpSession
4. Model/ModelMap
5. Map<String,Object>
注:ModelMap, Model, Map<String,Object>都是使用的request请求作用域:只能是请求转发后,后面才能取得值。