一、概述
1、springmvc 特点
- 注解开发很方便;
- 支持rest风格url;
2、HelloWorld程序
- 导包:四个spring 核心包、一个aop包、两个 web 包和一个logging 包;
- 配置 web xml 就是配置一个 dispatcherServlet,设置开机自启,指定springmvc配置文件位置;
- 配置springmvc文件,就是一个包扫描和一个视图解析器(前后缀),还有注解驱动的配置!!!
- 写一个类用@controller 标记,其中的方法用@requestMapping来实现和url 的映射关系;
二、基本使用(注解开发)
1、@requestMapping 注解
(1)可以用在方法和类上,起到窄化请求的作用;
(2)其中的属性还包含 method、param 和 header,都是更加精确请求的作用;
(3)@PathVariable 注解指定 url 占位符和方法参数之间的映射;
2、参数相关注解
(1)@RequestParam注解
- 作用就是映射请求参数;
- 注解有三个属性:value(请求参数的名字)、required(默认为true)、defaultValue(请参的默认值)
(2)@RequestHeader 和 @CookieValue 注解
- 作用就是将请求头和cookie 的信息映射到方法的参数;
- 注解的属性和用法都和requestParam 差不多;
(3)请求参数映射到 pojo
- 保证请求参数的名字和pojo 的属性名一致即可自动完成映射,还支持级联属性;
- 名字不一则无法映射,相应的值为 null;
(4)方法参数还支持 servlet 的原生 API,支持的类型包括:
- request、response、session、Principal
- InputStream、outputStream、reader、writer
3、模型数据处理
(1)方法返回 ModelAndView
- mv 可以包含视图和模型的信息;最终这些数据都是存放到 request 域中;
(2)方法可以添加 Map 或者 Model 类型的参数
(3)@sessionAttributes
- 这个注解是类注解,不能修饰方法;
- 可以通过名称指定也可以通过类型来指定放到 session 中的数据;
4、目标方法 pojo 类型入参过程
(1)@ModelAttribute注解:这个注解标记的方法会在每个目标方法执行前被执行
1、基本过程
- 执行这个注解修饰的方法,从数据库中取出对象放入 map,键值类名首字母小写;
- 从 map 中取出对象,并把表单传来的请求参数赋值到对象的相应属性中;
- 对象传入目标方法参数;
2、修饰目标方法参数
- springmvc 会用这个注解中指定的名称到 implicitModel 去找对象,找到就直接入参;
- 同时会将这个名称为key,pojo对象为 value 存到 request 中;
(2)pojo 入参过程
- 目标方法 pojo 类型参数可以用 @ModelAttribute 指定 pojo 对象的键名,也可以用默认的键名(全小写类名)到 implicitModel 中去找相应的 pojo 对象,找到了则作为入参传入;
- implicitModel 中的 pojo 对象来源于 @ModelAttribute 修饰的方法中存入到 map 中的 pojo 对象;
- implicitModel 中没有的话,springmvc 就会检查当前的 Controller 是否有 @SessionAttributes 修饰,若有的话就会从session 中找键值对应的 value,存在的话直接入参,不存在则会抛出异常;
- 如果没有 @SessionAttributes 的注解的或者该键值不包括在注解的值里面的话,则会通过反射来创建一个 pojo 对象作为方法的入参;
- key 和 pojo 保存在 implicitModel 中,进而保存到 request 中;
(3)使用 @sessionAttributes 注解抛出异常的解决方法
- sessionAttributes 中的名称和方法参数 modelAttribute 中指定的名称不一致即可;
- 要么就是必须得有 modelAttribute 标记的方法,保证能够取到 sessionAttributes 名称对应的对象就不会抛异常;
5、视图解析
(1)视图解析流程
- 目标方法无论返回的是 string、model还是 mv,最终都是包装成 modelAndView返回;
- 视图的作用:渲染模型数据;
- 视图解析器的作用:将逻辑视图转换为物理视图;
- 常用的视图解析器:BeanNameViewResolver 和 InternalResourceViewResolver;配置多个解析器的话存在优先级的;
(2)jstlView 和 view-controller 标签
- 项目加入jstl 的jar,springmvc 自动将视图解析为 jstlView;
- 若要使用 jstl fmt 标签要在 springmvc 的配置文件中配置一个 messageSource;
- view-controller 和 annotion-driven 标签合起来使用可以实现直接将请求跳转到视图,不用经过 handler;
(3)自定义视图和重定向
- 自定义视图:实现view 接口,重写 render 方法;最后还要在 springmvc 的配置文件中配置beanNameViewresolver,注意解析器的优先级;
- 转发和重定向:就是在 return 的 String 中加入前缀 forward: 或者 redirect:
三、补充
1、RESTFULL-CRUD
(1)CRUD 示例
- 新增:/order post
- 删除:/order/1 delete
- 修改:/order/1 put
- 查询:/order/1 get
(2)put 和 delete 请求怎么发送
- web xml 中配置 HiddenhttpMethodFilter;
- 发送 post 请求;
- 表单中增加一个 name=“_method” 的隐藏域,其值是 delete 和 put;
(3)spring 的表单标签
- 自带数据的回显功能;
- 数据回显的前提是 form 的 commandName属性的值要和 request 域中存放的 pojo 对象的键值一致;
- 还支持级联属性的写法;
(4)springmvc 的静态资源映射配置
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:annotation-driven></mvc:annotation-driven>
(5)a 标签的 get 请求转 post 通过 js 完成
- js 中用return false 阻止 a 标签点击的默认行为;
(6)方法入参的时候注意:
- 如果目标方法的参数没有用@ ModelAttribute注解指定键值,springmvc 就会自动用第一个字母小写的类名到 implicitModel中去找对应的pojo 对象;
- @modelAttribute注解修饰的方法 map 在 put 放入 pojo 对象的时候为避免出错,最好就用类名第一个字母小写作为键名;
2、数据绑定
(1)数据绑定的流程:核心就是DataBinder
(2)数据转换
- springmvc 内置了很多类型转换器,一般情况下不需要我们自己写;
- 自定义类型转换器
- 第一步:实现 Converter<S,T>接口,重写方法实现想要的类型转换;
- 第二步:在 spring 的 ioc 容器中配置convertionService;
- 第三步:mvc:annotion-driven注解中配置 convertionService,将这个注册到 springmvc 的上下文中;
<mvc:annotation-driven conversion-service="conversionService2"></mvc:annotation-driven>
<!-- myconveter config-->
<bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.stan.test.MyConverter"></bean>
</set>
</property>
</bean>
(3)关于mvc:annotation-driven
- 这个标签会自动注册RequestMappingHandlerMapping 、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver 三个bean;
- 此外还支持配置convertionService,还支持格式化注解(@NumberFormat annotation、@DateTimeFormat)验证注解(@Valid)请求响应体注解(@RequestBody 和 @ResponseBody)
(4)@InitBinder 注解
- @InitBinder 标识的方法,可以对 WebDataBinder 对 象进行初始化;
- WebDataBinder 是 DataBinder 的子类,用 于完成由表单字段到 JavaBean 属性的绑定 ;
- @InitBinder方法不能有返回值,它必须声明为void;
- @InitBinder方法的参数通常是WebDataBinder;
3、数据格式化
(1)前提
- 数据格式化相关的bean:FormattingConversionServiceFactroyBean;
- <mvc:annotation-driven/> 默认创建的ConversionService 实例即为FormattingConversionServiceFactroyBean;
- 如果自定义类型转换器配置了 conversionService 一定要手动配置 FormattingConversionServiceFactroyBean;
(2)日期格式化和数值格式化示例
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
@NumberFormat(pattern="#,###,###.#")
private Float salary;
4、数据校验
(1)校验框架
- JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架, 已包含在 JavaEE 6.0 中;
- Hibernate Validator 是 Bean Validation 的参考实现 .;
- Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint
(2)可以实现的校验
Constraint | 详细信息 |
---|---|
@Null | 被注释的元素必须为 null |
@NotNull | 被注释的元素必须不为 null |
@AssertTrue | 被注释的元素必须为 true |
@AssertFalse | 被注释的元素必须为 false |
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max, min) | 被注释的元素的大小必须在指定的范围内 |
@Digits (integer, fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 |
@Past | 被注释的元素必须是一个过去的日期 |
@Future | 被注释的元素必须是一个将来的日期 |
@Pattern(value) | 被注释的元素必须符合指定的正则表达式 |
Hibernate Validator 独有的注解 | |
@Email | 被注释的元素必须是电子邮箱地址 |
@Length | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串的必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
(3)校验的流程
- LocalValidatorFactoryBean是实现校验的bean;
- annotion-driven会默认装配好一个 LocalValidatorFactoryBean;
- 在处理方法的入参上标注@valid 注解,入参还可以加一个 bindingResult的参数;
- 需校验的 Bean 对象和其绑定结果对象bindingResult或错误对象时成对出现的,bindingResult 跟在 bean 的后面,之间不允许声明其他的入参;
- 在对应 pojo 的属性字段上加上校验注解;
- 在方法里获取校验的结果(getFieldError、getFieldErrors、getFieldValue、getErrorCount);
- 在页面上显示错误( 错误信息会随一个隐含模型传到jsp,页面直接用<form:errors path=“userName”>就可以获取);
@NotEmpty
private String lastName;
@Valid Employee employee,BindingResult bindingResult
(4)错误提示消息的国际化
- 建一个国际化properties文件,里面错误的键名类似Pattern.user.password,值是要显示的消息;
- 在 spring 的ioc 容器里配置一个 messageSource 注册国际化资源文件;
5、JSON处理
(1)步骤
- 加入三个 jackson 的jar;
- 写目标方法返回值为 json 对应的对象和集合;
- 在方法加上responseBody 的注解;
(2)原理
- 底层是通过 HttpMessageConverter<T> 来实现的,具体的原理如下:
- spring提供两种使用途径:
6、国际化和文件上传
(1)国际化
- 使用
- 原理
(2)文件上传
- 基于fileUpload 组件,fileupload依赖于 commons io;
- IOC 容器中配置 MultipartResolver
7、拦截器的使用
(1)拦截器的基本使用
- 写一个类继承 handlerIntercepter,重写三个方法;
- 在 spring 中配置自己写的拦截器;
(2)拦截器的配置
- 普通配置
- 配置拦截器的(不)作用的路径
(3)拦截器各个方法的执行时机
(4)多个拦截器的执行顺序
- 正常情况(左) 和 有 prehand 方法return false 的情况(右)