SpringMVC应用的开发步骤
1.在web.xml文件中定义前端控制器DispatcherServlet来拦截用户请求。在web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架接入web应用中。
例如,开发SpringMVC应用的第1步就是在web.xml文件中增加如下配置片段:
<!-- 定义Spring MVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 让Spring MVC的前端控制器拦截所有请求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.如果需要以post方式提交请求,则定义包含表单数据的JSP页面。如果仅仅只是以get方式发送请求,则无须经过这一步。
3.定义处理用户请求的Handle类,可以实现Controller接口或使用@Controller注解。
这一步也是所有MVC框架中必不可少的,因为这个DispatcherServlet就是MVC中的C,也就是前端控制器,该控制器负责接收请求,并将请求分发给对应的Handle,即实现Controller接口的Java类,而该Java类负责调用后台业务逻辑代码来处理请求。
MVC框架的底层机制是:前端Servlet接收到用户请求后,通常会对用户请求进行简单预处理,例如解析、封装参数等,然后通过反射来创建Controller实例,并调用Controller的指定方法(实现Controller接口的是handleRequest方法,而使用基于注解的控制器可以任意方法)来处理用户请求。
当Servlet拦截用户请求后,有两种解决方案来知道创建哪个Controller接口的实例。1):利用xml配置文件,例如在xml配置文件中描述hello请求对应使用HelloController类。这就可以让MVC框架知道创建哪个Controller接口的实例。2)利用注解,例如使用注解@Controller描述一个类,并使用注解@RequestMapping(value="/hello")描述hello请求对应的方法。这样也可以让MVC框架知道创建哪个Controller接口的实例并调用哪个方法处理请求。
在SpringMVC框架中,控制器实际上由两个部分共同组成,即拦截所有用户请求和处理请求的通用代码都由前端控制器DispatcherServlet完成,而实际的业务控制(诸如调用后台业务逻辑代码,返回处理结果等)则由Controller处理。
4.配置Handle。Java领域的绝大部分MVC框架都非常喜欢使用xml文件来进行配置管理,这在以前是一种思维定势。即配置哪个请求对应哪个Controller进行处理,从而让前端控制器根据该配置来创建合适的Controller实例,并调用该Controller的业务控制方法。
例如,可以采用如下代码片段来配置Handle:
<!--配置Handle,映射“/hello”请求-->
<bean name="/hello" class="org.fkit.controller.HelloController"/>
在Spring2.5之后,推荐使用注解来配置Handle:
@Controller
public class HelloController{
@RequestMapping(value="/hello")
public ModelAndView hello(){
...
}
}
上面的配置片段指定如果用户请求URL为hello,则使用org.fkit.controller.HelloController来处理。现在几乎所有的框架都使用“约定优于配置”的思想,也就是采用约定方式来规定用户请求地址和Handle之间的对应关系。
5.编写视图资源
当Handle处理用户请求结束后,通常会返回一个ModelAndView对象,该对象中应该包含的视图名和模型,这个视图名就代表需要显示的物理视图资源。如果Handle需要把一些数据传给视图资源,则可以通过模型对象。
经过上面的5个步骤,即可基本完成一个SpringMVC处理流程的开发,也就是可以执行一次完整的请求->响应过程。
SpringMVC请求->响应的完整工作流程如下:
1.用户向服务器发送请求,请求被Spring的前端控制器DispatcherServlet截获。
2.DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有的相关的对象,包括Handler对象以及Handler对象对应的拦截器,这写对象会被封装到一个HandlerExecutionChain对象当中返回。
3.DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。HandlerAdapter的设计符合面对对象中的单一职责原则,代码架构清晰,便于维护,最重要的是,代码可复用性高。HandlerAdapter会被用于处理多种Handler,调用Handler实际处理请求的方法,例如hello方法。
4.提取请求中的模型数据,开始执行Handler(Controller)。在填充Handler的入参过程中,根据配置,Spring将帮你做一些额外的工作。
消息转换:将请求消息(如Json、xml等数据)转换为一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换,如String转换成Integer、Double等。
数据格式化:对请求消息进行数据格式化,如将字符串转换为格式化数字或格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5.Handler执行完成后,DispatcherServlet返回一个ModelAndView对象,ModelAndView对象中应该包含视图名或视图名和模型。
6.根据返回的ModelAndView对象,选择一个合适的ViewReslover(视图解析器)返回给DispatcherServlet。
7.ViewReslover结合Model和View来渲染视图。
8.将视图渲染结果返回给客户端。
以上8个步骤,DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver等对象协同工作,完成SpringMVC请求->响应的整个工作流程,这些对象所完成的工作对于开发者来说都是不可见的,开发者并不需要关心这些对象如何工作,只需要在Handler(Controller)当中完成对请求的业务处理。
对于MVC框架,控制器(Controller)执行业务逻辑,用户产生模型数据(Model),而视图(View)则用于渲染模型数据。如何将模型数据传递给视图是SpringMVC框架的一项工作,SpringMVC提供了多种途径输出模型数据,如:Model和ModelMap,ModelAndView、@ModelAttribute、@SessionAttributes。
关于spingmvc-config.xml文件,最基本的有两步:
step1:
<!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean -->
<context:component-scan base-package="org.fkit.controller"/>
step2(视图解析器):
<!-- 视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix">
<value>/WEB-INF/content/</value>
</property>
<!-- 后缀 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>