1 类型转换器概述
- ConversionService 是 Spring 类型转换体系的核心接口。
- 可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC 容器中定义一个
ConversionService. Spring 将自动识别出 IOC 容器中的 ConversionService,并在 Bean 属性配置及 Spring MVC 处理方法入参绑定等场合使用它进行数据的转换
- 可通过 ConversionServiceFactoryBean 的 converters 属性注册自定义的类型转换器
- 例如:
2 Spring支持的类型转换器
① Spring 定义了 3 种类型的转换器接口,实现任意一个转换器接口都可以作为自定 义转换器注册到 ConversionServiceFactoryBean 中:
② Converter<S,T>:将 S 类型对象转为 T 类型对象
③ ConverterFactory:将相同系列多个 “同质” Converter 封装在一起。如果希望将 一种类型的对象转换为另一种类型及其子类的对象(例如将 String 转换为 Number 及 Number 子类(Integer、Long、Double 等)对象)可使用该转换器工 厂类
④ GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进 行类型转换
3 自定义类型转换器示例
1) 需求:字符串转换为对象。
2) 步骤:
- 定义页面
<form action=”empAdd” method=”POST”> <!– 解决问题: 1.数据类型转换 2.数据格式 3.数据校验 自定义类型转换器: 将字符串转换为Employee对象,完成添加功能 BirthDay :<input type=”text” name=”birthDay”/><br><br> –> <!– 字符串格式:lastName-email-gender-department.id 例如:GG-gg@atguigu.com-0-105 –> Employee : <input type=”text” name=”employee”/> <input type=”submit” value=”Submit”><br><br> </form> |
- 控制器方法
package com.atguigu.springmvc.crud.handlers;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam;
import com.atguigu.springmvc.crud.dao.EmployeeDao; import com.atguigu.springmvc.crud.entities.Employee;
@Controller public class TypeConversionHandler {
@Autowired private EmployeeDao employeeDao ;
// String -> Employee 需要类型转换器帮忙 @RequestMapping(“/empAdd”) public String empAdd(@RequestParam(value=”employee”) Employee employee){ System.out.println(“TypeConversionHandler – ” + employee); employeeDao.save(employee); return “redirect:/empList”; } } |
- 自定义类型转换器
package com.atguigu.springmvc.converter;
import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component;
import com.atguigu.springmvc.crud.entities.Department; import com.atguigu.springmvc.crud.entities.Employee;
/** * 将字符串转换为Employee对象类型 */ @Component public class StringToEmployeeConverter implements Converter<String, Employee> {
@Override public Employee convert(String source) { if(source!=null){ String[] strs = source.split(“-“); if(strs!=null && strs.length == 4){ String lastName = strs[0]; String email = strs[1]; Integer gender = Integer.parseInt(strs[2]); Integer deptId = Integer.parseInt(strs[3]); Department dept = new Department(); dept.setId(deptId); Employee employee = new Employee(null,lastName,email,gender,dept); System.out.println(source+”–converter–“+employee); return employee ; } } return null; } } |
- 声明类型转换器服务
<bean id=”conversionService” class=”org.springframework.context.support.ConversionServiceFactoryBean“> <property name=”converters”> <set> <!– 引用类型转换器 –> <ref bean=”stringToEmployeeConverter“/> </set> </property> </bean> |
- <mvc:annotation-driven conversion-service=”conversionService“/> 会将自定义的
ConversionService 注册到 Spring MVC 的上下文中
4 Debug调试
- 增加新的转换器,之前的转换器是否还好使呢?好使。
查看,框架出厂设置,与目前将我们的自定义类型转换器加入出厂设置中。
- 当配置了<mvc:annotation-driven/>后,会自动加载
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
和org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
5 <mvc:annotation-driven/>配置在什么时候必须配置?
- 直接配置响应的页面:无需经过控制器来执行结果 ;但会导致其他请求路径失效,需要配置mvc:annotation-driven标签
<mvc:view-controller path=”/success” view-name=”success”/> |
- RESTful-CRUD操作,删除时,通过jQuery执行delete请求时,找不到静态资源,需要配置mvc:annotation-driven标签
<mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 WEB 应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 继续处理。 |
- 配置类型转换器服务时,需要指定转换器服务引用
<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的
ConversionService 注册到 Spring MVC 的上下文中
- 后面完成JSR 303数据验证,也需要配置
5.1 关于 <mvc:annotation-driven /> 作用
- <mvc:annotation-driven /> 会自动注册:
RequestMappingHandlerMapping 、
RequestMappingHandlerAdapter 与
ExceptionHandlerExceptionResolver 三个bean。
- 还将提供以下支持:
- 支持使用 ConversionService 实例对表单参数进行类型转换
- 支持使用 @NumberFormat、@DateTimeFormat 注解完成数据类型的格式化
- 支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证
- 支持使用 @RequestBody 和 @ResponseBody 注解
- 结合源码分析(在bean对象的set方法上设置断点进行调试)
- 既没有配置 <mvc:default-servlet-handler/>
也没有配置 <mvc:annotation-driven/>
都没有配置情况下,AnnotationMethodHandlerAdapter是默认出厂设置,干活 的(过期)。
另外:conversionService是null(类型转换器是不起作用的)
四月 30, 2016 3:52:21 下午 org.springframework.web.servlet.PageNotFound noHandlerFound 警告: No mapping found for HTTP request with URI [/SpringMVC_03_RESTFul_CRUD/scripts/jquery-1.9.1.min.js] in DispatcherServlet with name ‘springDispatcherServlet’ |
- 配置了 <mvc:default-servlet-handler/> 但没有配置 <mvc:annotation-driven/>
AnnotationMethodHandlerAdapter被取消,解决了静态资源查找,但是 @RequestMapping不好使了。
- 既配置了 <mvc:default-servlet-handler/> 又配置 <mvc:annotation-driven/>【重要】
AnnotationMethodHandlerAdapter被替换成RequestMappingHandlerAdapter来 干活了。
如果没有配置<mvc:annotation-driven/>标签时,conversionService为null.
AnnotationMethodHandlerAdapter已经过时,Spring3.2推荐RequestMappingHandlerAdapter来替代。所以说,默认情况下,没有配置这两个配置时,HelloWorld 程序可以正常运行,但是,涉及到静态资源查找的时候,就必须配置这个<mvc:annotation-driven/>配置了
上一篇: java培训数据绑定流程原理及debug调试流程
下一篇: java培训之InitBinder注解