一、简介
Spring MVC是Spring框架中用于web应用开发的一个模块,是Spring提供的一个基于MVC设计模式的优秀web开发框架,本质相当于是Servlet,Spring MVC作为控制器(Controller)来建立模型与视图的数据交互。
Spring MVC框架采用松耦合可插拔的组件结构,具有高度可配置性,相对比其他MVC框架更具扩展性和灵活性。而且其本身就作为Spring框架的一部分,所以与Spring的整合更是无缝衔接。 在Spring MVC框架中,Controller替代Servlet来担负控制器的职责,负责接收请求并调用相应的Model处理,处理器完成业务处理返回处理结果,再调用相应的View对处理结果进行渲染,最终传送响应消息到客户端。
二、工作原理解析
在整个SpringMVC框架中,处于核心地位的是前端控制器(DispatcherServlet),由它来接收所有的请求,并将具体工作委托给其他组件进行处理,负责协调组织不同组件完成请求处理并返回响应。
————————根据具体步骤来解析:
注:以下步骤都对应上图的步骤,读者可对照着学习,以下是具体的解释
1. 首先用户发送HTTP请求到web服务器,若匹配DispatcherServlet的请求映射路径(在web.xml中指定),则web容器就将该请求转交给DispatcherServlet处理。
2. 前端控制器DispatcherServlet根据请求信息(如URL、请求参数、HTTP方法等)及HandelerMapping的配置(在<servlet-name>-servlet.xml中配置)找到处理请求的处理器(Handler)。
3. 通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter接口可以理解为具体使用Handler来干活的人。接口里只有3个方法,如下。supports(Object handler)方法:判断是否可以使用某个Handler。
handler方法:具体使用Handler处理请求。
getLastModified方法:获取资源的Last-Modified。4. 在请求信息到达真正调用Handler的处理方法之前,Spring MVC还会完成许多工作,它会将请求信息以一定方式转换并绑定到请求方法的入参中,对于入参的对象会进行数据转换、数据格式化和数据校验等操作。当这些做完之后才真正调用Handler的处理方法进行相应的业务逻辑处理,处理器完成业务处理后返回一个ModelAndView对象给DispatcherServlet,ModelAndView对象包含了逻辑视图名和模型数据信息。
5. ModelAndView对象中包含的“逻辑视图名”并不是真正的视图对象,DispatcherServlet会通过一个叫ViewResolver将逻辑视图名解析成真正的视图对象View。注:Spring MVC 可灵活配置数据显示的视图是JSP还是其他模板语言如velocity。
6. 当得到真实的视图对象View后,DispatcherServlet会使用ModelAndView对象中的模型数据对View进行数据渲染。
7. 最终客户端获得响应消息。
————————至此运行原理解析,大功告成。
Spring MVC 特点:
- 清晰的角色划分,从Model、Controller、View这三方面各司其职。
- 灵活的配置功能,因为Spring的核心是IoC,所以Spring MVC也可以把各种类当做Bean来通过XML进行配置。
- 提供了大量的控制器接口和实现类。
- 真正做到了View层的实现无关,完全可以根据需求使用velocity或者jsp技术开发。
- 国际化支持和面向接口编程
三、小Demo起步
1、创建一个maven工程,springMVC主要需要spring-webmvc
和spring-web
这2个jar包。
2、配置web.xml,主要是加载配置DispatcherServlet前端控制器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通过设置contextConfigLocation来指定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-cfg.xml</param-value>
</init-param>
<!--表示容器一旦启动就加载此DispatcherServlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3、配置springmvc-cfg.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--包扫描,实现注解驱动bean定义,同时将bean自动注入容器中使用-->
<context:component-scan base-package="com.xiaojiang.controller"/>
<!--该配置会自动注册处理器映射和处理器适配器这两个bean,springMVC需要这两个bean来完成对@Controller和@RequestMapping等注解的支持-->
<mvc:annotation-driven/>
<!--配置视图解析器,注意前缀和后缀最后拼接起来的完整路径有无错误,尤其是/和少了上一级文件夹-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
4、编写控制器来处理请求
/**
* FileName: IndexController
* Author: 小江
* Date: 2019/3/21 11:56
* History:
*/
package com.xiaojiang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/test")
public class IndexController {
//入门
@RequestMapping("/index")
public String index(){
return "index";
}
//传参,控制器传给视图参数,注意参数名都要一致,否则注入不进去值
@RequestMapping("/send")
public ModelAndView sendParam(String username){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username",username);
modelAndView.setViewName("index");
return modelAndView;
}
//传参,视图传给控制器参数
@RequestMapping("/welcome")
public String welcome(@RequestParam(value="user",required=false) String user){
System.out.println("视图传给控制器的参数:"+user);
return "welcome";
}
}
5、最后在自己编写对应想要的jsp页面去显示信息就好了,起步完毕。
传参可通过ModelAndView和Model方式来传参,ModelAndView通过addObject(key,value)这个方法传参,Model通过addAttribute(key,value)这个方法传参。