用久了 SpringBoot,深受其约定大于配置的便利性毒害之后,我想回归到 SpringMVC 时代,看看 SpringMVC 开发模式中用户是如何参与的。本文就来体验一下 SpringMVC 时代开发的流程。
一个典型的 SpringMVC 请求流程如图所示,详细分为 12 个步骤:
整个过程清晰明了,下面我们将结合实际实验来理解这整个过程。
实验环境如下:
这里我是用 IDEA 来搭建的基于 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 来进行处理
从上一步的配置可以看到,我们定义的 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
<%@ page cOntentType="text/html; charset=" pageEncoding="UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <title>学生名单</title> </head> <body> <h3>学生列表</h3> <table width="300px;" border=1> <tr> <td>姓名</td> <td>学号</td> </tr> <c:forEach items="${studentList}" var="student" > <tr> <td>${student.name}</td> <td>${student.ID}</td> </tr> </c:forEach> </table> </body> </html>
结合本步骤和上一步骤,视图和控制器都已编写完成,由于我们之前配置的处理器映射器为:BeanNameUrlHandlerMapping,因此接下来我们还需要在 mvc-dispatcher.xml 文件中配置一个可被 url 映射的 controller 的 bean,供处理器映射器 BeanNameUrlHandlerMapping 查找:
<bean name="/test.action" class="cn.codesheep.controller.TestController" />
启动 Tomcat 服务器,然后浏览器输入:
http://localhost:8080/test.action
数据渲染 OK。
备注:当然本文所使用的全是非注解的配置方法,即需要在 XML 中进行配置并且需要遵循各种实现原则。而更加通用、主流的基于注解的配置方法将在后续文章中详述。
作者更多的 SpringBt 实践文章在此:
如果有兴趣,也可以抽点时间看看作者一些关于容器化、微服务化方面的文章:
![]() | 1 jerrry 2018-06-11 07:41:00 +08:00 via Android 不错 |
![]() | 2 yushiro 2018-06-11 08:27:27 +08:00 via iPhone 收藏了慢慢看,正好需要 |
3 Jeffrey8888 2018-06-11 08:44:49 +08:00 挺好,请楼主多多分享 |
4 SKull4 2018-06-11 08:57:24 +08:00 有些错别字,建议再查一下 |
![]() | 5 jatai 2018-06-11 08:59:09 +08:00 想入门 java 来的,我一个渣渣看不懂,弱弱地问下:现在的趋势不是前后端分离吗,这会不会有点开倒车的? |
6 trys1 2018-06-11 09:03:21 +08:00 via Android 是该前后端分离了呀 |
7 KgM4gLtF0shViDH3 2018-06-11 09:10:32 +08:00 |
![]() | 8 wly19960911 2018-06-11 09:11:54 +08:00 @jatai #5 我认为是该前后端分离,但是有时候这些东西不应该不学,难免会碰到这种场景的需要,毕竟现在还有人用 jsp,freemarker,thymeleaf 这种模板引擎。 |
9 zqguo 2018-06-11 09:13:21 +08:00 落后 |
![]() | 10 sagaxu 2018-06-11 09:27:02 +08:00 via Android |
11 KgM4gLtF0shViDH3 2018-06-11 09:31:18 +08:00 @sagaxu #10 那是你对前端非常熟的情况下,而且用那些东西对 seo 很不好,搞到最后比不分离还复杂。 |
13 maxiujun 2018-06-11 09:47:56 +08:00 via iPad 楼主深受框架便利性毒害,应该回归纯 java,最好 servlet 也别用,tomcat 自己写个。 |
![]() | 14 enzohobmg 2018-06-11 09:51:42 +08:00 毒害就过分了 哈哈哈哈 恶心确实有点 |
![]() | 15 liuxey 2018-06-11 09:53:04 +08:00 可以再回归一下本质,用 ServerSocket 写一个 rest 服务? :doge: |
![]() | 16 lhx2008 2018-06-11 09:54:17 +08:00 via Android @maxiujun 我也是这么想的,boot 的话也就省几个配置文件而已,毒害真的说不上。如果说了解下 boot 里面的 springmvc 的运行方式也还不错。 |
![]() | 17 littleghosty 2018-06-11 10:02:55 +08:00 @bestkayle 小公司的 java 程序员都是前后端一把抓吗? |
![]() | 18 chinvo 2018-06-11 10:05:29 +08:00 via iPhone 楼主深受 Java 便利性的毒害,赶紧汇编自己从网卡驱动写一个 |
19 KgM4gLtF0shViDH3 2018-06-11 10:05:37 +08:00 @littleghosty #17 PHP 基本都是的,如果没有专门的前端或者没有前端服务器不都是一把梭。 |
![]() | 20 hansonwang99 OP mark |
![]() | 21 woscaizi 2018-06-11 10:41:40 +08:00 @littleghosty #17 是的 |
![]() | 22 littleghosty 2018-06-11 10:43:07 +08:00 |
![]() | 23 codeyung 2018-06-11 10:44:52 +08:00 sb 也可以 用 mvc 一样的... 感觉重复工作 |
![]() | 24 littleghosty 2018-06-11 10:45:20 +08:00 @bestkayle 小公司还用 JSP JSTL EL ? |
25 ljw15011154354 2018-06-11 10:48:16 +08:00 前后端分类和大公司小公司有什么关系啊???现在是 2018 年不是 2008 年 |
![]() | 26 pynix 2018-06-11 10:48:37 +08:00 有人居然喜欢配置。。。 |
![]() | 27 ming2050 2018-06-11 10:49:14 +08:00 via iPhone 一本正紧的开倒车 |
![]() | 28 jeffson 2018-06-11 10:52:05 +08:00 路过 |
![]() | 29 vjnjc 2018-06-11 11:29:44 +08:00 via Android 问一下 spring boot 有啥缺点么,我用了半年好像还没遇到。。。 |
![]() | 30 hansonwang99 OP 滴滴滴,倒车请注意 |
![]() | 31 undeflife 2018-06-11 13:46:53 +08:00 看不懂在做什么 spring boot 里对 http 请求的处理部分不还是 spring-web,spring-webmvc 在处理吗?同样可以用 jsp,ModelAndView 如果你实在喜欢 web.xml 完全可以保留 web.xml 文件 感觉你只是单纯的不喜欢注解,用 spring 1.x 就好了. |
![]() | 32 misaka19000 2018-06-11 13:49:58 +08:00 建议楼主再写一个“从 SpringMVC 到 Servlet ” |
![]() | 33 VoidChen 2018-06-11 17:29:34 +08:00 再倒一车,来个 ssh ( status+spring+hibernate )。。。手动狗头=-= |
![]() | 34 james2013 2018-06-11 22:00:28 +08:00 ![]() 楼主来到 V2EX 论坛,便排出 9 篇大文,唠叨着深受 SpringBoot 毒害,要回到 SpringMVC 什么的. 众人围着楼主,提问声音不绝于耳,请注意倒车,楼主再写一个“从 SpringMVC 到 Servlet ”,前后端分离很不错,为啥还要用 jsp? 楼主红着脖子喃喃道,你们懂什么? 写了这么多代码和配置文件,你们不知道楼主我有多么努力么? 多么熟悉 SpringMVC 原理,你们会配置 SpringMVC 么? 领导整体听到我的键盘声噼噼啪啪,一直夸我很努力,有上进心,说我每天最晚走,下个月就给我颁发最多加班奖. JSP 传承这么多年了,不能断送在我们这一代程序员手里. ... 顿时倒车滴滴声响成一片,帖子中充满了欢快的气息. |
![]() | 35 ren2881971 2018-06-11 22:06:48 +08:00 springboot 不好用么。。。 |
![]() | 36 wdlth 2018-06-11 22:34:53 +08:00 只是倒了一个 JSP 的车…… 干脆直接用 maven 建个 webapp 得了,还用啥 spring …… Servlet 一把梭。 |
37 ifsoar0712 2018-06-12 09:29:34 +08:00 @james2013 doge: |
![]() | 38 MarcoM 2018-06-12 11:13:43 +08:00 很好 学习了 |
![]() | 39 fumichael 2018-06-12 11:46:44 +08:00 我这还在用 struts2 …,诶… |
40 introle 2018-06-12 14:00:40 +08:00 收藏了 |
![]() | 41 james2013 2018-06-12 22:19:05 +08:00 @ifsoar0712 哈哈,昨晚那时突然就来灵感了,就写下了 |
42 breezeFP 2018-06-13 14:40:41 +08:00 “深受其约定大于配置的便利性毒害之后,我想回归到 SpringMVC 时代”,直接用 servlet 得了 |
![]() | 43 jack80342 2018-06-13 23:31:39 +08:00 嘿嘿嘿翻译了最新的 Spring Boot 2.0 的英文文档,欢迎 Fork,https://www.gitbook.com/book/jack80342/spring-boot/details |