正文
V A I O
概述
用久了SpringBoot,深受其约定大于配置的便利性毒害之后,我想回归到SpringMVC时代,看看SpringMVC开发模式中用户是如何参与的。本文就来体验一下SpringMVC时代开发的流程。
SpringMVC架构模式
SpringMVC请求处理流程
一个典型的SpringMVC请求流程如图所示,详细分为12个步骤:
-
用户发起请求,由前端控制器DispatcherServlet处理
-
前端控制器通过处理器映射器查找hander,可以根据XML或者注解去找
-
处理器映射器返回执行链
-
前端控制器请求处理器适配器来执行hander
-
处理器适配器来执行handler
-
处理业务完成后,会给处理器适配器返回ModeAndView对象,其中有视图名称,模型数据
-
处理器适配器将视图名称和模型数据返回到前端控制器
-
前端控制器通过视图解析器来对视图进行解析
-
视图解析器返回真正的视图给前端控制器
-
前端控制器通过返回的视图和数据进行渲染
-
返回渲染完成的视图
-
将最终的视图返回给用户,产生响应
整个过程清晰明了,下面我们将结合实际实验来理解这整个过程。
SpringMVC项目搭建
实验环境如下:
-
IntelliJ IDEA 2018.1 (Ultimate Edition)
-
SpringMVC 4.3.9.RELEASE
-
Maven 3.3.9
这里我是用IDEA来搭建的基于Maven的SpringMVC项目,搭建过程不再赘述,各种点击并且下一步,最终创建好的项目架构如下:
基于Maven的SpringMVC项目
添加前端控制器配置
使用了SpringMVC,则所有的请求都应该交由SpingMVC来管理,即要将所有符合条件的请求拦截到SpringMVC的专有Servlet上。
为此我们需要在
web.xml
中添加SpringMVC的前端控制器DispatcherServlet:
<!--springmvc前端控制器-->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc-dispatcher.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
该配置说明所有符合.action的url,都交由mvc-dispatcher这个Servlet来进行处理
编写SpringMVC核心XML配置文件
从上一步的配置可以看到,我们定义的mvc-dispatcher Servlet依赖于配置文件
mvc-dispatcher.xml
,在本步骤中我们需要在其中添加三个方面的配置
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
SpringMVC的处理器映射器有多种,这里的使用的BeanNameUrlHandlerMapping其映射规则是将bean的name作为url进行处理
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
SpringMVC的处理器适配器也有多种,这里的使用的SimpleControllerHandlerAdapter是Controller实现类的适配器类,其本质是执行Controller中的handleRequest方法。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
这里配置了InternalResourceViewResolver视图解析器后,其会根据controller方法执行之后返回的ModelAndView中的视图的具体位置,来加载对应的界面并绑定数据
编写控制器
这里模拟的是一个打印学生名单的Service,我们编写的控制器需要将查询到的学生名单数据通过ModelAndView渲染到指定的JSP页面中
public class TestController implements Controller {
private StudentService studentService = new StudentService();
@Override
public ModelAndView handleRequest( HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
List<Student> studentList = studentService.queryStudents();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("studentList",studentList);
modelAndView.setViewName("/WEB-INF/views/studentList.jsp");
return modelAndView;
}
}
class StudentService {
public List<Student> queryStudents() {
List<Student> studentList = new ArrayList<Student>();
Student hansonwang = new Student();
hansonwang.setName("hansonwang99");
hansonwang.setID("123456");
Student codesheep = new Student();
codesheep.setName("codesheep");
codesheep.setID("654321");
studentList.add(hansonwang);
studentList.add(codesheep);
return studentList;
}
}
编写视图文件
这里的视图文件是一个jsp文件,路径为:
/WEB-INF/views/studentList.jsp