文章目录
SpringMVC总览
1.处理静态资源
如:<script src="https://code.jquery.com/jquery-3.4.0.js"></script>
等
<!--
default-servlet-handler 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的
Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理
一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定
-->
<mvc:default-servlet-handler/>
2.mvc:annotation-driven的作用
- 会自动注册:RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver三个bean
- 支持使用 ConversionService 实例对表单参数进行类型转换,也可对数据类型进行注解驱动
支持使用 @NumberFormat annotation、@DateTimeFormat 注解完成数据类型的格式化
支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证
支持使用 @RequestBody 和 @ResponseBody 注解
3.数据绑定
3.1 流程
1.Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创 建 DataBinder 实例对象 2.DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式 化工作。将 Servlet 中的请求信息填充到入参对象中
3.调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
4.Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参
3.2 @InitBinder
由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,用 于完成由表单字段到 JavaBean 属性的绑定
@InitBinder方法不能有返回值,它必须声明为void。
@InitBinder方法的参数通常是WebDataBinder
@InitBinder
public void initBinder(WebDataBinder binder){
binder.setDisallowedFields("lastName");
}
3.3 数据格式化
装配了 FormattingConversionServiceFactroyBean 后,就可以在 Spring MVC 入参绑定及模型数据输出时使用注解驱动了。mvc:annotation-driven/ 默认创建的 ConversionService 实例即为 FormattingConversionServiceFactroyBean
1.数值格式化 @NumberFormat
可对类似数字类型的属性进行标注,它拥有两个互斥的属性:
style:类型为 NumberFormat.Style。用于指定样式类– 型,包括三种:Style.NUMBER(正常数字类型)、 Style.CURRENCY(货币类型)、 Style.PERCENT( 百分数类型)
pattern:类型为 String,自定义样式,如patter="#,###";
2.日期格式化 @DateTimeFormat
可对java.util.Date、java.util.Calendar、java.long.Long 时间 类型进行标注:
pattern 属性:类型为字符串。指定解析/格式化字段数据的模式,– 如:”yyyy-MM-dd hh:mm:ss” iso 属性:类型为 DateTimeFormat.ISO。指定解析/格式化字段数据– 的ISO模式,包括四种:ISO.NONE(不使用)、ISO.DATE(yyyy-MM-dd) 、ISO.TIME(hh:mm:ss.SSSZ)、ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)
style 属性:字符串类型。通过样式指定日期时间的格式,由两位字符组成,第一位表示日期的格式,第二位表示时间的格式:S:短日 期/时间格式、M:中日期/时间格式、L:长日期/时间格式、F:完整 日期/时间格式、-:忽略日期或时间格式
@Past //校验过去时间
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
@NumberFormat(pattern="#,###,###.#")
private Float salary;
3.4 数据校验
JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证
Mavan中的依赖:mvc:annotation-driven/ 会默认装配好一个 LocalValidatorFactoryBean但不支持@past
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId> <!--JSR-303规范API包-->
<version>2.0.1.Final</version>
</dependency>
@NotEmpty
private String lastName;
@Email
private String email;
@Past //校验过去时间
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
mvc:annotation-driven/ 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @valid 注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作,并将校 验结果保存在被校验入参对象之后的 BindingResult 或 Errors 入参中,还会将所有校验结果保存到 “隐含模型” (最终将通过 HttpServletRequest 的属性列表暴露给 JSP 视图对象)
注意: 需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参
@RequestMapping(value="/emp", method=RequestMethod.POST)
public String save(@Valid Employee employee, Errors result,
Map<String, Object> map){
System.out.println("save: " + employee);
if(result.getErrorCount() > 0){
System.out.println("出错了!");
for(FieldError error:result.getFieldErrors()){
System.out.println(error.getField() + ":" + error.getDefaultMessage());
}
//若验证出错, 则转向定制的页面
map.put("departments", departmentDao.getDepartments());
return "input";
}
employeeDao.save(employee);
return "redirect:/emps";
}
错误页面的信息显示
Email: <form:input path="email"/>
<form:errors path="email"></form:errors>
如果需要定制显示的提示:
@Email(message="邮件地址格式不对")
private String email;
4 请求响应JSON化
使用 HttpMessageConverter 将请求信息转化并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,Spring 提供两种径:使用 @RequestBody / @ResponseBody 对处理方法的进行标注分别对应入参/返回值;使用 HttpEntity / ResponseEntity 作为处理方法的入参或返回值
和JSON所需的依赖包:
5 文件上传
dispatcher-servlet.xml
<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
页面
<form action="testFileUpload" method="POST" enctype="multipart/form-data">
File: <input type="file" name="file"/>
Desc: <input type="text" name="desc"/>
<input type="submit" value="Submit"/>
</form>
6 拦截器
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必 须实现HandlerInterceptor接口
preHandle():
该方法在目标方法之前被调用.
若返回值为 true, 则继续调用后续的拦截器和目标方法.
若返回值为 false, 则不会再调用后续的拦截器和目标方法.
可以考虑做权限. 日志, 事务等.
postHandle():
调用目标方法之后, 但渲染视图之前. 可以对请求域中的属性或视图做出修改.
afterCompletion():
渲染视图之后被调用. 释放资源
单个拦截器执行顺序:preHandle -> handler方法 -> postHandle -> 渲染视图render -> afterCompletion
两个拦截器正常执行:preHandle1 -> preHandle2(true) -> handler方法 -> postHandle2 -> postHandle1 -> 渲染视图render -> afterCompletion2 -> afterCompletion1
两个拦截器非正常执行:preHandle1 -> preHandle1(false)-> afterCompletion1
<mvc:interceptors>
<!-- 配置自定义的拦截器 -->
<bean class="com.atguigu.springmvc.interceptors.FirstInterceptor"></bean>
<!-- 配置拦截器(不)作用的路径 -->
<mvc:interceptor>
<mvc:mapping path="/emps"/>
<bean class="com.atguigu.springmvc.interceptors.SecondInterceptor"></bean>
</mvc:interceptor>
<!-- 配置 LocaleChanceInterceptor -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>