Spring MVC中数据绑定流程原理及应用

数据绑定流程原理:

① Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象;

② DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中;

③ 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象;

④ Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参;

Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义类型转换器:

在这里插入图片描述

ConversionService 是 Spring 类型转换体系的核心接口。

1.可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC 容器中定义一个 ConversionService. Spring 将自动识别出 IOC 容器中的 ConversionService,并在 Bean 属性配置及 Spring MVC 处理方法入参绑定等场合使用它进行数据的转换

2.可通过 ConversionServiceFactoryBean 的 converters 属性注册自定义的类型转换器
在这里插入图片描述
案例需求:

将字符串类型转化成Employee对象;
完整的Employee对象需要lastname,email,gender,department.id等属性;
希望通过“ [email protected]” 这种输入的方式建立一个对象并回显表单;

SpringMVC配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        ">
	
	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="cn.zhang.springmvc"></context:component-scan>
	
	<!-- 配置视图解析器 :如何把handler方法返回值解析为实际的物理视图-->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!--  
		default-servlet-handler 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
		它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的 
		Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理;
		一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
		若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定		
	-->
	<mvc:default-servlet-handler/>
	
	<!--在实际开发中都需要配置mvc:annotation-driven标签  -->
	<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
	
	<!--配置ConversionService (<ref bean="employeeConverter"/>为转化器代码类首字母小写)-->
	<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
		<property name="converters">
			<set>
				<ref bean="employeeConverter"/>
			</set>
		</property>
	</bean>
		
</beans>

<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的 ConversionService 注册到 Spring MVC 的上下文中;

测试类:

@Controller
public class SpringMVCTest {
	
	@Autowired
	private EmployeeDao employeeDao;
	
	@RequestMapping("/testConversionServiceConverer")
	public String testConverter(@RequestParam("employee") Employee employee) {
		System.out.println("save: " + employee);
		employeeDao.save(employee);
		return "redirect:/emps";
	}
}

提交页面:
(省略了页面中的其他信息)

	<form action="testConversionServiceConverer" method="POST">
		<!-- lastname-email-gender-department.id 例如: zh-[email protected]-0-105-->
		Employee: <input type="text" name="employee"/>
		<input type="submit" value="Submit"/>
	</form>
	<br><br>

转化器代码:( 实现了Converter<String, Employee>)

@Component
public class EmployeeConverter implements Converter<String, Employee> {

	@Override
	public Employee convert(String source) {
		if(source!=null) {
			String [] vals = source.split("-");//通过-进行分割
			if(vals != null && vals.length == 4) {
				String lastName = vals[0];
				String email = vals[1];
				Integer gender = Integer.parseInt(vals[2]);
				Department department =new Department();
				department.setId(Integer.parseInt(vals[3]));
				Employee employee = new Employee(null,lastName,email,gender,department);
				System.out.println(source +" [convert] "+employee);
				return employee;
			}
		}
		return null;
	}
}

初始表单信息:
在这里插入图片描述
点击按钮(通过需求的输入格式输入原始数据):
在这里插入图片描述
结果表单回显且可发现新加入的Employee(zh)对象:
在这里插入图片描述
同时控制台输出:

[email protected] [convert] Employee [id=null, lastName=zh, [email protected], gender=0, department=Department [id=105, departmentName=null], birth=null, salary=null]
save: Employee [id=null, lastName=zh, [email protected], gender=0, department=Department [id=105, departmentName=null], birth=null, salary=null]

即测试Success!!

发布了11 篇原创文章 · 获赞 0 · 访问量 102

猜你喜欢

转载自blog.csdn.net/qq_43395576/article/details/104555658