SpringBoot 提交form 表单会把数据自动封装到person对象中
<form action="/saveuser" method="post"> 姓名: <input name="userName" value="zhangsan"/> <br/> 年龄: <input name="age" value="18"/> <br/> 生日: <input name="birth" value="2019/12/10"/> <br/> 宠物姓名:<input name="pet.name" value="阿猫"/><br/> 宠物年龄:<input name="pet.age" value="5"/> <!-- 宠物: <input name="pet" value="啊猫,3"/>--> <input type="submit" value="保存"/> </form>
发送post 请求
/** * 数据绑定:页面提交的请求数据(GET、POST)都可以和对象属性进行绑定 * @param person * @return */ @PostMapping("/saveuser") public Person saveuser(Person person){ return person; }
结果:
1.POJO封装原理
挨个判断所有参数解析器那个支持解析这个参数
- ServletModelAttributeMethodProcessor参数解析器
是否为简单类型。
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
@Nullable
public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
String name = ModelFactory.getNameForParameter(parameter);
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null) {
mavContainer.setBinding(name, ann.binding());
}
Object attribute = null;
BindingResult bindingResult = null;
if (mavContainer.containsAttribute(name)) {
attribute = mavContainer.getModel().get(name);
}
else {
// Create attribute instance
try {
//创建空对象
attribute = createAttribute(name, parameter, binderFactory, webRequest);
}
catch (BindException ex) {
if (isBindExceptionRequired(parameter)) {
// No BindingResult parameter -> fail with BindException
throw ex;
}
// Otherwise, expose null/empty value and associated BindingResult
if (parameter.getParameterType() == Optional.class) {
attribute = Optional.empty();
}
bindingResult = ex.getBindingResult();
}
}
if (bindingResult == null) {
// Bean property binding and validation;
// skipped in case of binding failure on construction.
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
if (binder.getTarget() != null) {
if (!mavContainer.isBindingDisabled(name)) {
bindRequestParameters(binder, webRequest);
}
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
// Value type adaptation, also covering java.util.Optional
if (!parameter.getParameterType().isInstance(attribute)) {
attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
}
bindingResult = binder.getBindingResult();
}
// Add resolved attribute and BindingResult at the end of the model
Map<String, Object> bindingResultModel = bindingResult.getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return attribute;
}
//创建空对象
attribute = createAttribute(name, parameter, binderFactory, webRequest);
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
WebDataBinder :web数据绑定器,将请求参数的值绑定到指定的JavaBean里面
WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中
//将请求数据跟对象绑定
bindRequestParameters(binder, webRequest);
GenericConversionService:在设置每一个值的时候,找它里面的所有converter那个可以将这个数据类型(request带来参数的字符串)转换到指定的类型(JavaBean -- Integer)
byte -- > file
2.自定义Converter
发送请求,自定义Converte解析 宠物: <input name="pet" value="啊猫,3"/>的参数封装到javaBean
<form action="/saveuser" method="post"> 姓名: <input name="userName" value="zhangsan"/> <br/> 年龄: <input name="age" value="18"/> <br/> 生日: <input name="birth" value="2019/12/10"/> <br/> <!-- 宠物姓名:<input name="pet.name" value="阿猫"/><br/>--> <!-- 宠物年龄:<input name="pet.age" value="5"/>--> 宠物: <input name="pet" value="啊猫,3"/> <input type="submit" value="保存"/> </form>
WebMvcConfigurer
//1、WebMvcConfigurer定制化SpringMVC的功能
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Converter<String, Pet>() {
@Override
public Pet convert(String source) {
// 啊猫,3
if(!StringUtils.isEmpty(source)){
Pet pet = new Pet();
String[] split = source.split(",");
pet.setName(split[0]);
pet.setAge(Integer.parseInt(split[1]));
return pet;
}
return null;
}
});
}
};
}
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
返回值中Converter加入了自定义的Converter
运行结果