美文网首页
Spring Boot Web 请求处理-自定义参数绑定

Spring Boot Web 请求处理-自定义参数绑定

作者: Tinyspot | 来源:发表于2022-12-22 21:33 被阅读0次

数据绑定:页面提交的请求数据与对象属性进行绑定
表单:

<form action="/save/user" method="post">
    用户名:<input name="name"/> <br>
    邮箱:<input name="email"/> <br>
    <input type="submit" value="save">
</form>

数据接收:

@PostMapping("/save/user")
public Map<String, Object> save(User user) {
    Map<String, Object> map = new HashMap<>();
    map.put("content", JSON.toJSONString(user));
    return map;
}
  1. ServletInvocableHandlerMethod#invokeAndHandle 里的 invokeForRequest()
  2. InvocableHandlerMethod#invokeForRequest 里的 getMethodArgumentValues()
public class InvocableHandlerMethod extends HandlerMethod {
    protected Object[] getMethodArgumentValues(...) {
        if (!this.resolvers.supportsParameter(parameter)) {
        }
    }
}

POJO 封装,参数处理器 ServletModelAttributeMethodProcessor

public boolean supportsParameter(MethodParameter parameter) {
    return (parameter.hasParameterAnnotation(ModelAttribute.class) ||
                (this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType())));
    }

BeanUtils#isSimpleProperty()

public static boolean isSimpleProperty(Class<?> type) {
        Assert.notNull(type, "'type' must not be null");
        return isSimpleValueType(type) || type.isArray() && isSimpleValueType(type.getComponentType());
    }

继续解析
ModelAttributeMethodProcessor#resolveArgument

// Create attribute instance
attribute = createAttribute(name, parameter, binderFactory, webRequest);

此时会创建一个空对象 User

WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
bindRequestParameters(binder, webRequest);

WebDataBinder web数据绑定器

public class WebDataBinder extends DataBinder {
}
public class DataBinder implements PropertyEditorRegistry, TypeConverter {
    private final Object target;
    private ConversionService conversionService;
}

3.3 DataBinder#applyPropertyValues

AbstractNestablePropertyAccessor#setPropertyValue(PropertyValue pv)

nestedPa = getPropertyAccessorForPropertyPath(propertyName);
nestedPa.setPropertyValue(tokens, pv);
valueToApply = convertForProperty(tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());

convertForProperty()
image.png

相关文章