SpringMVC框架学习一:SpringMVC 处理请求流程
SpringMVC概述
Spring MVC 为展现层提供的基于MVC设计理念的优秀框架,是目前最主流的MVC框架之一,它包括许多优点:
1. 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无需实现任何接口
2. 支持 REST 风格的 URL 请求
2. 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性
先简单描述Spring MVC处理请求的过程
与大多数基于 Java 的 Web 框架一样,Spring MVC 所有请求都会通过一个前端控制器 DispatcherServlet,它的任务是将请求发送给 Spring MVC 控制器。控制器是一个用于处理请求的组件。在典型的应用程序中可能会有多个控制器,DispatcherServlet 需要知道请求发送给哪个控制器。所以 DispatcherServlet 会查询一个或多个处理器映射来确定请求的下一站在哪。处理器映射会根据请求所携带的URL信息来进行决策。
一旦选择了合适的控制器, DispatcherServlet 会将请求发送给选中的控制器。到达控制器,请求会卸下其负载(用户提交的信息)并耐心等待控制器处理这些信息(实际上,设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象)。
控制器在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示。这些信息称为模型(model)。不过仅仅给用户返回原始信息是不够的,这些信息还需要以用户友好的方式进行格式化,一般是HTML。所以信息需要发送一个视图(view),通常会是JSP页面。
控制器所做的最后一件事是将模型数据打包,并标出用于渲染输出的视图名称。它接下来会连同模型和视图名称发送回 DispatcherServlet。
这样控制器就不会与特定的视图相耦合,传递给 DispatcherServlet 的视图名称并不直接表示某个特定的 JSP。实际上,它甚至并不能确定视图是JSP。相反,它仅仅传递了一个逻辑名,这个名字将会用来查找用来产生正真结果的视图。DispatcherServlet 将会使用视图解析器来将逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是JSP。
最后,DispatcherServlet 交付模型数据,请求任务就完成了。视图使用模型数据渲染输出,并且通过这个输出将响应对象传递给客户端。
整体架构如图
我们结合图与Spring MVC中的类再来描述一下请求整个过程
① 整个过程始于客户端发送一个HTTP 请求,Web应用服务器收到这个请求,如果匹配 DispatcherServlet 的请求映射路径(在web.xml中指定),Web容器将该请求转交给DispatcherServlet处理。
② DispatcherServlet 接收到这个请求之后,将根据请求信息(包括URL、HTTP方法、请求报文头、请求参数。Cookies等)及 HandlerMapping 的配置找到处理请求的处理器(Handler)。可将 HandlerMapping 看成路由控制器,将 Handler看成目标主机。值得注意的是:Spring MVC 中并没有定义一个 Handler接口,实际上任何一个Object都可以成为请求处理器。
③ 当DispatcherServlet 根据 HandlerMapping 得到对应当前请求的Handler之后,通过HandlerAdapter 对 Handler 进行封装,再以统一的适配器接口调用Handler。HandlerAdapter 是 Spring MVC 框架级接口,顾名思义,HandlerAdapter 是一个适配器,它用统一的接口对各种 Handler 方法进行调用。
④ 处理器完成业务逻辑的处理后将返回一个 ModelAndView 给 DispatcherServlet,ModelAndView 包含了视图逻辑名和模型数据信息。
⑤ ModelAndView 中包含的是"逻辑视图名"而非真正的视图对象,DispatcherServlet 借由 ViewResolver 完成逻辑视图名到真实视图对象的解析工作。
⑥ 当得到真实的视图对象 View 之后,DispatcherServlet 就使用这个 View 对象对 ModelAndView 中的模型数据进行视图渲染。
⑦ 最终客户端得到的响应消息可能是一个普通的HTML页面,也可能是一个XML页面或JSON串,甚至是一张图片或一个PDF文档等不同的媒体形式。
下面我们通过实现一个 HelloWorld 程序来展示请求流程
创建工程步骤分为:
1. 加入jar包
2. 在web.xml中配置 DispatcherServlet
3. 加入 Spring MVC 的配置文件
4. 编写处理请求的处理器,并标识为处理器
5. 编写视图
web.xml 配置 DispatcherServlet:DispatcherServlet默认加载路径为 /WEB-INF/<servletName-servlet>.xml 的 Spring配置文件,启动 WEB 层的 Spring 容器。也可以通过contextConfigLocation 初始化参数自定义配置文件的位置和名称。
1 <!-- 默认路径下的 Spring 配置文件,名字及路径为/springmvc-test/WebContent/WEB-INF/springDispatcherServlet-servlet.xml --> 2 <servlet> 3 <servlet-name>springDispatcherServlet</servlet-name> 4 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 5 <load-on-startup>1</load-on-startup> 6 </servlet> 7 8 <servlet-mapping> 9 <servlet-name>springDispatcherServlet</servlet-name> 10 <url-pattern>/</url-pattern> 11 </servlet-mapping>
1 <!-- 自定义的spring 配置文件可以放置在类路径src下,名字在属性中指定为springmvc.xml --> 2 <servlet> 3 <servlet-name>springDispatcherServlet</servlet-name> 4 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 5 <init-param> 6 <param-name>contextConfigLocation</param-name> 7 <param-value>classpath:springmvc.xml</param-value> 8 </init-param> 9 10 <load-on-startup>1</load-on-startup> 11 </servlet> 12 13 <servlet-mapping> 14 <servlet-name>springDispatcherServlet</servlet-name> 15 <url-pattern>/</url-pattern> 16 </servlet-mapping>
创建 Spring MVC 配置文件
1 <!-- 配置自动扫描的包 --> 2 <context:component-scan base-package="com.bupt.springmvc"/> 3 4 <!-- 配置视图解析器:将视图逻辑全路径名解析为/WEB-INF/views/<viewsName>.jsp (需在/WEB-INF下新建一个名为views(自定义)的文件夹) --> 5 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 6 <property name="prefix" value="/WEB-INF/views/"/> 7 <property name="suffix" value=".jsp"/> 8 </bean>
创建请求处理器类
1 package com.bupt.springmvc.handler; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 6 //@Controll注解将一个POJO转化为处理请求的控制器 7 @Controller 8 public class HelloWorld 9 { 10 private static final String SUCCESS = "success"; 11 12 /** 13 * 1. 使用 @RequestMapping 注解来映射请求的URL 14 * 2. 返回值会通过视图解析器解析为实际的物理视图,对于InternalResourceViewResolver视图解析器 15 * 通过 prefix + returnValue + suffix 这种方法来得到实际物理视图,再执行转发操作,如本例中会转发到 /WEB-INF/views/success.jsp 16 * 17 */ 18 @RequestMapping("/helloworld") 19 public String hello() 20 { 21 System.out.println("hello world"); 22 return SUCCESS; 23 } 24 }
编写转发页面 success.jsp
1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" 2 pageEncoding="ISO-8859-1"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <title>Insert title here</title> 7 </head> 8 <body> 9 <h4>Success Page</h4> 10 </body> 11 </html>
编写请求页面 index.jsp
1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" 2 pageEncoding="ISO-8859-1"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <title>Insert title here</title> 7 </head> 8 <body> 9 <a href="helloworld">Hello World</a> 10 </body> 11 </html>
启动服务器访问 index.jsp 页面,点击超链接,可以看到页面跳转至 success.jsp页面,同时控制台打印 hello world。
posted on 2016-07-01 09:53 Traveling_Light_CC 阅读(479) 评论(0) 编辑 收藏 举报