Parámetros del décimo objeto personalizado de Springboot

objeto encapsulado personalizado

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

¿Por qué los datos de solicitud enviados por la página están encapsulados en nuestro objeto personalizado?

Nuestro objeto personalizado es procesado por esto.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
Nuestro objeto personalizado está encapsulado con él.
inserte la descripción de la imagen aquí
Juzgará si es un tipo de datos simple o no.

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));
	}

El núcleo de la encapsulación de tipo personalizado está aquí

@Override
	@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;
	}

este es nuestro núcleo
inserte la descripción de la imagen aquí

Carpeta WebDataBinder = binderFactory.createBinder(webRequest, atributo, nombre);

Echemos un vistazo a esta carpeta.
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
Aquí está el objeto creado para poner los datos
inserte la descripción de la imagen aquí
, todos somos enviados desde http, es decir, todos los datos enviados son de tipo String,
este es nuestro convertidor.
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
Vemos que hay 124 convertidores aquí, por ejemplo, el que seleccionamos es para convertir String a Enum,
inserte la descripción de la imagen aquí
y también hay String a Object.
inserte la descripción de la imagen aquí

El siguiente cuadro es responsable de convertir los datos de cadena de solicitud recibidos en el tipo de datos en el objeto que especificamos,
como Cadena en Entero
inserte la descripción de la imagen aquí

El binder en este paso es el que creamos para poner nuestro objeto y la solicitud nativa

inserte la descripción de la imagen aquí
Después de este paso, hemos vinculado los datos
, que consiste en vincular el valor de nuestros datos a través del método de llamada de reflexión. Se
inserte la descripción de la imagen aquí
utiliza el proceso de encapsulación .ServletModelAttributeMethodProcessor

public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {
    
    
	
    @Override//本方法在ModelAttributeMethodProcessor类,
	public boolean supportsParameter(MethodParameter parameter) {
    
    
		return (parameter.hasParameterAnnotation(ModelAttribute.class) ||
				(this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType())));
	}

	@Override
	@Nullable//本方法在ModelAttributeMethodProcessor类,
	public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
    
    

		...

		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 (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)) {
    
    
                    //web数据绑定器,将请求参数的值绑定到指定的JavaBean里面**
					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;
	}
}

Resumir

WebDataBinder: el archivador de datos web vincula el valor del parámetro de solicitud al JavaBean especificado

WebDataBinder utiliza los convertidores que contiene para convertir los datos solicitados en el tipo de datos especificado. Nuevamente encapsulado en JavaBean

GenericConversionService: al configurar cada valor, busque todos los convertidores que puedan convertir este tipo de datos (cadena con parámetros traídos por la solicitud) al tipo especificado (JavaBean - Integer)

Principio del convertidor personalizado

inserte la descripción de la imagen aquí
Usamos, para separar
nuestro analizador personalizado

 @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) {
    
    
                        if(!StringUtils.isEmpty(source)){
    
    
                            Pet pat = new Pet();
                            String [] split = source.split(",");
                            pat.setName(split[0]);
                            pat.setAge(String.valueOf(Integer.valueOf(split[1])));
                            return pat;
                        }
                        return null;
                    }
                });
            }
        };
    }

Examinamos el analizador y descubrimos que 125 eran originalmente 124 de nuestros analizadores personalizados y lo pusimos aquí
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
Aquí le damos la vuelta
inserte la descripción de la imagen aquí
y lo enviamos
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_47431361/article/details/123754249
Recomendado
Clasificación