资深软件开发工程师,业余马拉松选手。
我们已经介绍了Java Web的基础:Servlet容器,以及标准的Servlet组件:
- Servlet:能处理HTTP请求并将HTTP响应返回;
- JSP:一种嵌套Java代码的HTML,将被编译为Servlet;
- Filter:能过滤指定的URL以实现拦截功能;
- Listener:监听指定的事件,如ServletContext、HttpSession的创建和销毁。
此外,Servlet容器为每个Web应用程序自动创建一个唯一的实例,这个实例就代表了Web应用程序本身。
在MVC高级开发中,我们手撸了一个MVC框架,接口和Spring MVC类似。如果直接使用Spring MVC,我们写出来的代码类似:
但是,Spring提供的是一个IoC容器,所有的Bean,包括Controller,都在Spring IoC容器中被初始化,而Servlet容器由JavaEE服务器提供(如Tomcat),Servlet容器对Spring一无所知,他们之间到底依靠什么进行联系,又是以何种顺序初始化的?
在理解上述问题之前,我们先把基于Spring MVC开发的项目结构搭建起来。首先创建基于Web的Maven工程,引入如下依赖:
- org.springframework:spring-context:6.0.0
- org.springframework:spring-webmvc:6.0.0
- org.springframework:spring-jdbc:6.0.0
- jakarta.annotation:jakarta.annotation-api:2.1.1
- io.pebbletemplates:pebble-spring6:3.2.0
- ch.qos.logback:logback-core:1.4.4
- ch.qos.logback:logback-classic:1.4.4
- com.zaxxer:HikariCP:5.0.1
- org.hsqldb:hsqldb:2.7.0
以及依赖:
- org.apache.tomcat.embed:tomcat-embed-core:10.1.1
- org.apache.tomcat.embed:tomcat-embed-jasper:10.1.1
这个标准的Maven Web工程目录结构如下:
其中,是标准web目录,存放,编译的class,第三方jar,以及不允许浏览器直接访问的View模版,目录存放所有静态文件。
在目录中存放的是Java程序读取的classpath资源文件,除了JDBC的配置文件外,我们又新增了一个,这是Logback的默认查找的配置文件:
上面给出了一个写入到标准输出的Logback配置,可以基于上述配置添加写入到文件的配置。
在中就是我们编写的Java代码了。
和普通Spring配置一样,我们编写正常的后,只需加上注解,就“激活”了Spring MVC:
除了创建、、外,需要额外创建几个用于Spring MVC的Bean:
并不是必须的,但我们在这里创建一个默认的,只覆写,目的是让Spring MVC自动处理静态文件,并且映射路径为。
另一个必须要创建的Bean是,因为Spring MVC允许集成任何模板引擎,使用哪个模板引擎,就实例化一个对应的:
通过指定和来确定如何查找View。上述配置使用Pebble引擎,指定模板文件存放在目录下。
剩下的Bean都是普通的,但Controller必须标记为,例如:
如果是普通的Java应用程序,我们通过方法可以很简单地创建一个Spring容器的实例:
但是问题来了,现在是Web应用程序,而Web应用程序总是由Servlet容器创建,那么,Spring容器应该由谁创建?在什么时候创建?Spring容器中的Controller又是如何通过Servlet调用的?
在Web应用中启动Spring容器有很多种方法,可以通过Listener启动,也可以通过Servlet启动,可以使用XML配置,也可以使用注解配置。这里,我们只介绍一种最简单的启动Spring容器的方式。
第一步,我们在中配置Spring MVC提供的:
初始化参数指定使用注解配置的,配置文件的位置参数指向的完整类名,最后,把这个Servlet映射到,即处理所有URL。
上述配置可以看作一个样板配置,有了这个配置,Servlet容器会首先初始化Spring MVC的,在启动时,它根据配置创建了一个类型是的IoC容器,完成所有Bean的初始化,并将容器绑到上。
因为持有IoC容器,能从IoC容器中获取所有的Bean,因此,接收到所有HTTP请求后,根据Controller方法配置的路径,就可以正确地把请求转发到指定方法,并根据返回的决定如何渲染页面。
最后,我们在中通过方法启动嵌入式Tomcat:
上述Web应用程序就是我们使用Spring MVC时的一个最小启动功能集。由于使用了JDBC和数据库,用户的注册、登录信息会被持久化:
有了Web应用程序的最基本的结构,我们的重点就可以放在如何编写Controller上。Spring MVC对Controller没有固定的要求,也不需要实现特定的接口。以为例,编写Controller只需要遵循以下要点:
总是标记而不是:
一个方法对应一个HTTP请求路径,用或表示GET或POST请求:
需要接收的HTTP参数以标注,可以设置默认值。如果方法参数需要传入、或者,直接添加这个类型的参数即可,Spring MVC会自动按类型传入。
返回的ModelAndView通常包含View的路径和一个Map作为Model,但也可以没有Model,例如:
返回重定向时既可以写,也可以直接返回String:
如果在方法内部直接操作发送响应,返回表示无需进一步处理:
对URL进行分组,每组对应一个Controller是一种很好的组织形式,并可以在Controller的class定义出添加URL前缀,例如:
实际方法的URL映射总是前缀+路径,这种形式还可以有效避免不小心导致的重复的URL映射。
可见,Spring MVC允许我们编写既简单又灵活的Controller实现。
使用Spring MVC,在注册、登录等功能的基础上增加一个修改口令的页面。
下载练习
使用Spring MVC时,整个Web应用程序按如下顺序启动:
- 启动Tomcat服务器;
- Tomcat读取并初始化;
- 创建IoC容器并自动注册到中。
启动后,浏览器发出的HTTP请求全部由接收,并根据配置转发到指定Controller的指定方法处理。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/9740.html