Spring In Action(第四版) chapter5读书笔记
搭建Spring MVC
配置DispatcherServlet
DispatcherServlet
是SpringMVC的核心,负责将请求路由到其它组件注:接下来将使用Java配置将
DispatcherServlet
配置到Servlet中,而不再使用web.xml文件
1 | /** |
AbstractAnnotationConfigDispatcherServletInitializer
剖析:
在Servlet 3.0环境中,容器会在类路径下查找实现javax.servlet.ServletContainerInitializer
接口的类,如果发现的话,就会用实现类来配置Servlet容器。Spring提供了这个接口的实现类,名为org.springframework.web.SpringServletContainerInitializer
,这个类反过来查找实现了org.springframework.web.context.WebApplicationContext
接口的类并将任务分配给它们完成。
Spring 3.2引入了一个便捷的WebApplicationContext
基础实现,也就是AbstractAnnotationConfigDispatcherServletInitializer
。
而上述编写的SpitterWebInitializer
类扩展了AbstractAnnotationConfigDispatcherServletInitializer
抽象类(同时也实现了WebApplicationContext
接口),因而当部署到Servlet 3.0中的容器中,容器会自动发现它,并用来配置Servlet上下文。
getRootConfigClasses
()/getServletConfigClasses()
对于这两个方法的理解,首先要理解DispatcherServlet
和一个Servlet监听器(即ContextLoaderListener
)的关系。
首先的区分SpringWeb项目中的两个应用上下文:
- 当
DispatcherServlet
启动时会创建Spring的应用上下文,并加载配置文件或者配置类中声明的bean,该上下文加载包含Web组件的bean,如控制器、视图解析器以及处理器映射; - 在SpringWeb项目中,通常还会有另一个应用上下文,该上下文是由
ContextLoaderListener
所创建,该上下文加载其它bean(不同于Web组件),这些bean通常是驱动应用后端的中间层和数据层组件。
实际上,AbstractAnnotationConfigDispatcherServletInitializer
会同时创建DispatcherServlet
和ContextLoaderListener
,
getServletConfigClasses()
方法返回带有@Configuration
注解的类将会用于定义DispatcherServlet
应用上下文的bean,而getRootConfigClasses()
方法返回带有@Configuration
注解的类将会用于定义ContextLoaderListener
应用上下文的bean。
对于配置类的编写:
1 |
|
控制器的编写
1 |
|
测试控制器
所用到jar包的maven依赖
1 | <!-- 测试jar包依赖 --> |
测试类的编写,做法:发起了对/
路径的GET请求,并断言结果视图的名称为’home’
1 | public class HomeControllerTest { |
传递模型数据到视图中
1、首先定义一个数据访问的Repository,数据来源随机数(照常理而言应来源于数据库,但此处重点在于传递),首先定义Repository接口及实现类:
1 | // 接口 |
2、编写控制器,用于接收请求返回数据及视图
1 |
|
3、定义视图Jsp页面
注意:web.xml的版本问题,过低可能导致EL表达式无效
1 | <%@ page import="spittr.Spittle" %> |
接收请求参数
SpringMVC允许以多种方式将客户端中的数据传送到控制器的处理控制方法中,包括:
- 查询参数(Query Parameter)
- 表单参数(Form Parameter)
- 路径参数(Path Paramter)
查询参数(Query Parameter)
在之前的的控制类中编写下述控制方法,将请求参数写在控制方法的形参中,使用注解@RequestParm
建立映射关系,注解参数value对应请求的参数名
1 | /** |
路径参数(Path Paramter)
例:获取某一条评论并展示
解决方法:
学习此部分内容前,想到的做法是转化成查询参数,即root?spittleId=5
,这样便可与查询参数一样进行查询,但这样的做法从面向资源的角度看是不合法的。
而SpringMVC提供了路径参数这一解决方法,即root/5
,即可达到目的,而具体控制器方法的编写如下
1 | /** |
这里的@RequestMapping(value = "/{spittleId}", method = RequestMethod.GET)
的value值用{}
框起表示占位符,在root/5
中代表5,而形参中@PathVariable(value = "spittleId")
表示参数与这个占位符形成映射关系,即spittleId=5
对于少量的请求参数用上述两种方法较为合适,而对于较多参数则应选用表单。
处理表单
对于大量参数,使用表单提交更为合适
操作步骤:
1、首先编写jsp表单视图
注:若未给表单指定action(提交到的地址),表单会提交到与展现是相同的URL路径上。
2、编写实体类,类中的属性应与表单的name属性对应
3、编写数据访问对象,用于存储用户信息及获取用户信息,模拟数据库功能,使用List集合模拟
4、编写注册成功的用户信息展示jsp视图
5、编写控制器
1 | /** |
表单校验
一个坑点,对于导入的依赖包(我使用的是maven项目)
之前对应找到网上最新的依赖,导入后发现@NotNull
等校验注解不起作用
1 | <!-- 用于表单的校验 --> |
能de出bug全凭运气,欢乐谋篇博客贴的两个依赖(和上面比只有org.hibernate.validator
的版本不一样),换完后bug解决了
1 | <dependency> |
但是还是很迷:
1、org.hibernate.validator
低版本时包含javax.validation
包,使用低版本时包含org.hibernate.validator
即可
2、org.hibernate.validator 7.0.0
版本将javax.validation
分离出去,但是相应注解失效,还是不懂为什么