data exchange
data binding process
- The Spring MVC main framework passes the ServletRequest object and the input parameter instance of the target method to the WebDataBinderFactory instance to create the DataBinder instance object
- DataBinder calls the ConversionService component assembled in the Spring MVC context to perform data type conversion and data formatting. Fill the request information in the servlet into the input object
- Call the Validator component to verify the data validity of the input parameter object that has been bound to the request message, and finally generate the data binding result BindingData object
- Spring MVC extracts the input parameter object and validation error object in BindingResult, and assigns them to the response input parameter of the processing method
- Spring MVC parses the target processing method through the reflection mechanism, and binds the request message to the input parameters of the processing method. The core component of data binding is DataBinder, which operates as follows:
There are many converters built into the Spring MVC context to do most of the Java type conversions ConversionService converters =
java.lang.Boolean -> java.lang.String :org.springframework.core.convert.support.ObjectToStringConverter@f874ca
java.lang.Character -> java.lang.Number : CharacterToNumberFactory@f004c9
java.lang.Character -> java.lang.String : ObjectToStringConverter@68a961
java.lang.Number -> java.lang.Character : NumberToCharacterConverter@1482ac5
java.lang.Number -> java.lang.String : ObjectToStringConverter@14888e8
java.lang.String -> java.lang.Boolean : StringToBooleanConverter@1ca6626
java.lang.String -> java.lang.Character : StringToCharacterConverter@1143800
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory@1bba86e
java.lang.String -> java.lang.Number : StringToNumberConverterFactory@18d2c12
java.lang.String -> java.util.Locale : StringToLocaleConverter@3598e1
java.lang.String -> java.util.Properties : StringToPropertiesConverter@c90828
java.lang.String -> java.util.UUID : StringToUUIDConverter@a42f23
java.util.Locale -> java.lang.String : ObjectToStringConverter@c7e20a
java.util.Properties -> java.lang.String : PropertiesToStringConverter@367a7f
java.util.UUID -> java.lang.String : ObjectToStringConverter@112b07f
……
custom type converter
- ConversionService is the core interface of Spring's type conversion system.
- You can use ConversionServiceFactoryBean to define a ConversionService in Spring's IOC container. Spring will automatically identify the ConversionService in the IOC container, and use it for data conversion in Bean property configuration and Spring MVC processing method input parameter binding and other occasions
- Custom type converters can be registered through the converters property of ConversionServiceFactoryBean
springmvc.xml added:
<!--配置conversionService-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConverter"></ref>
</set>
</property>
</bean>
Register the custom converter to the Spring MVC context, springmvc.xml continues to add:
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
Note the code: Based on my last blog post:
- EmployeeConverter.java
import com.ifox.restful_CRUD.entities.Department;
import com.ifox.restful_CRUD.entities.Employee;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
@Component
public class EmployeeConverter implements Converter<String,Employee> {
@Nullable
@Override
public Employee convert(String s) {
if (s != null){
String val[] = s.split("-") ;
if (val != null && val.length == 4){
String lastName = val[0] ;
String email = val[1] ;
Integer gender = Integer.parseInt(val[2]) ;
Department department = new Department() ;
department.setId(Integer.parseInt(val[3]));
Employee employee = new Employee(null,lastName,email, gender, department) ;
System.out.println(s +"--convert--"+ employee );
return employee ;
}
}
return null ;
}
}
- jsp page;
<form action="testConversionServiceConverer" method="post">
<%--格式示例: KK-kk@sicnu.com-0-105--%>
Employee: <input type="text" name="employee">
<input type="submit" value="Submit">
</form>
Input the data in [email protected] format, and after submitting, it will be converted into Employee through our custom converter.
- Controller class:
import com.ifox.restful_CRUD.dao.EmployeeDao;
import com.ifox.restful_CRUD.entities.Employee;
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;
@Controller
public class ConversionServiceConverer {
@Autowired
private EmployeeDao employeeDao ;
@RequestMapping("/testConversionServiceConverer")
public String testConversionService(@RequestParam("employee") Employee employee){
System.out.println("save:"+employee);
employeeDao.save(employee);
return "redirect:/emps" ;
}
}
Converters supported by Spring
Spring defines three types of converter interfaces, and any converter interface that implements it can be registered in the ConversionServiceFactroyBean as a custom converter:
Converter<S,T>
: Convert S type object to T type objectConverterFactory
: Encapsulates multiple "homogeneous" Converters of the same series together. If you want to convert an object of one type to an object of another type and its subclasses (for example, convert String to Number and Number subclass (Integer, Long, Double, etc.) objects) you can use the converter factory class- GenericConverter: Type conversion is performed according to the context information in the host class where the source class object and the target class object are located
About mvc:annotation-driven
<mvc:annotation-driven />
Three beans, RequestMappingHandlerMapping, RequestMappingHandlerAdapter and ExceptionHandlerExceptionResolver, are automatically registered.
The following support will also be provided:- Supports type conversion of form parameters using ConversionService instances
- Supports data type formatting using @NumberFormat annotation and @DateTimeFormat annotation
- Supports JSR 303 validation of JavaBean instances using the @Valid annotation
- Supports the use of @RequestBody and @ResponseBody annotations
@InitBinder
- The method identified by @InitBinder can initialize the WebDataBinder object. WebDataBinder is a subclass of DataBinder, which is used to complete the binding from form fields to JavaBean properties
- A @InitBinder method cannot have a return value, it must be declared void.
- The parameter of the @InitBinder method is usually WebDataBinder
handler:
@InitBinder
public void initBinder(WebDataBinder binder){
System.out.println("initBinder............");
//不自动绑定lastName属性
binder.setDisallowedFields("lastName");
//这样做会使得表单提交的lastName没有绑定
}