spring的9中messageConverter

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver
for (HttpMessageConverter<?> converter : this.messageConverters) {
Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter.getClass();
if (converter instanceof GenericHttpMessageConverter) {
GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter;
if (genericConverter.canRead(targetType, contextClass, contentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
}
if (inputMessage.getBody() != null) {
inputMessage = getAdvice().beforeBodyRead(inputMessage, parameter, targetType, converterType);
body = genericConverter.read(targetType, contextClass, inputMessage);
body = getAdvice().afterBodyRead(body, inputMessage, parameter, targetType, converterType);
}
else {
body = getAdvice().handleEmptyBody(null, inputMessage, parameter, targetType, converterType);
}
break;
}
}
else if (targetClass != null) {
if (converter.canRead(targetClass, contentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
}
if (inputMessage.getBody() != null) {
inputMessage = getAdvice().beforeBodyRead(inputMessage, parameter, targetType, converterType);
body = ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage);
body = getAdvice().afterBodyRead(body, inputMessage, parameter, targetType, converterType);
}
else {
body = getAdvice().handleEmptyBody(null, inputMessage, parameter, targetType, converterType);
}
break;
}
}
}
MappingJackson2HttpMessageConverter属于GenericHttpMessageConverter类型

spring反序列化参数
com.fasterxml.jackson.databind.deser.BeanDeserializer
/**
* Main deserialization method for bean-based objects (POJOs).
*/
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
// common case first
if (p.isExpectedStartObjectToken()) {
if (_vanillaProcessing) {
return vanillaDeserialize(p, ctxt, p.nextToken());
}
// 23-Sep-2015, tatu: This is wrong at some many levels, but for now... it is
// what it is, including "expected behavior".
p.nextToken();
if (_objectIdReader != null) {
return deserializeWithObjectId(p, ctxt);
}
return deserializeFromObject(p, ctxt);
}
return _deserializeOther(p, ctxt, p.getCurrentToken());
}
/**
* General version used when handling needs more advanced features.
*/
@Override
public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException
{
/* 09-Dec-2014, tatu: As per [#622], we need to allow Object Id references
* to come in as JSON Objects as well; but for now assume they will
* be simple, single-property references, which means that we can
* recognize them without having to buffer anything.
* Once again, if we must, we can do more complex handling with buffering,
* but let's only do that if and when that becomes necessary.
*/
if (_objectIdReader != null && _objectIdReader.maySerializeAsObject()) {
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)
&& _objectIdReader.isValidReferencePropertyName(p.getCurrentName(), p)) {
return deserializeFromObjectId(p, ctxt);
}
}
if (_nonStandardCreation) {
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(p, ctxt);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(p, ctxt);
}
Object bean = deserializeFromObjectUsingNonDefault(p, ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
/* 27-May-2014, tatu: I don't think view processing would work
* at this point, so commenting it out; but leaving in place
* just in case I forgot something fundamental...
*/
/*
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(p, ctxt, bean, view);
}
}
*/
return bean;
}
//先生成一个对象,值都为各个类型的默认值
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom deserializers
p.setCurrentValue(bean);
if (p.canReadObjectId()) {
Object id = p.getObjectId();
if (id != null) {
_handleTypedObjectId(p, ctxt, bean, id);
}
}
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(p, ctxt, bean, view);
}
}
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
String propName = p.getCurrentName();
do {
p.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(p, ctxt, bean, propName);
} while ((propName = p.nextFieldName()) != null);
}
return bean;
}
com.fasterxml.jackson.databind.deser.impl.MethodProperty
@Override
public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
Object instance) throws IOException
{
Object value = deserialize(p, ctxt);
try {
_setter.invoke(instance, value);
} catch (Exception e) {
_throwAsIOE(p, e, value);
}
}
StringDeserializer:对String类型的反序列化实现 所在包:com.fasterxml.jackson.databind.deser.std
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
if (p.hasToken(JsonToken.VALUE_STRING)) {
return p.getText();
}
JsonToken t = p.getCurrentToken();
// [databind#381]
if (t == JsonToken.START_ARRAY) {
return _deserializeFromArray(p, ctxt);
}
// need to gracefully handle byte[] data, as base64
if (t == JsonToken.VALUE_EMBEDDED_OBJECT) {
Object ob = p.getEmbeddedObject();
if (ob == null) {
return null;
}
if (ob instanceof byte[]) {
return ctxt.getBase64Variant().encode((byte[]) ob, false);
}
// otherwise, try conversion using toString()...
return ob.toString();
}
// allow coercions for other scalar types
String text = p.getValueAsString();
if (text != null) {
return text;
}
return (String) ctxt.handleUnexpectedToken(_valueClass, p);
}
BooleanDeserializer:对布尔类型的反序列化 所在包:com.fasterxml.jackson.databind.deser.std
@Override
public Boolean deserialize(JsonParser j, DeserializationContext ctxt) throws IOException
{
return _parseBoolean(j, ctxt);
}
protected final Boolean _parseBoolean(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonToken t = p.getCurrentToken();
if (t == JsonToken.VALUE_TRUE) {
return Boolean.TRUE;
}
if (t == JsonToken.VALUE_FALSE) {
return Boolean.FALSE;
}
// should accept ints too, (0 == false, otherwise true)
if (t == JsonToken.VALUE_NUMBER_INT) {
return Boolean.valueOf(_parseBooleanFromInt(p, ctxt));
}
if (t == JsonToken.VALUE_NULL) {
return (Boolean) getNullValue(ctxt);
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = p.getText().trim();
// [databind#422]: Allow aliases
if ("true".equals(text) || "True".equals(text)) {
return Boolean.TRUE;
}
if ("false".equals(text) || "False".equals(text)) {
return Boolean.FALSE;
}
if (text.length() == 0) {
return (Boolean) getEmptyValue(ctxt);
}
if (_hasTextualNull(text)) {
return (Boolean) getNullValue(ctxt);
}
return (Boolean) ctxt.handleWeirdStringValue(_valueClass, text,
"only \"true\" or \"false\" recognized");
}
// [databind#381]
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
p.nextToken();
final Boolean parsed = _parseBoolean(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
handleMissingEndArrayForSingle(p, ctxt);
}
return parsed;
}
// Otherwise, no can do:
return (Boolean) ctxt.handleUnexpectedToken(_valueClass, p);
}
protected boolean _parseBooleanFromInt(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// 13-Oct-2016, tatu: As per [databind#1324], need to be careful wrt
// degenerate case of huge integers, legal in JSON.
// ... this is, on the other hand, probably wrong/sub-optimal for non-JSON
// input. For now, no rea
// Anyway, note that since we know it's valid (JSON) integer, it can't have
// extra whitespace to trim.
//如果是在bool类型中传入数字,这个数字只要不是0都会解析会true
return !"0".equals(p.getText());
}
本文深入探讨了Spring MVC框架中9种messageConverter的工作原理,特别关注了MappingJackson2HttpMessageConverter作为GenericHttpMessageConverter的角色。同时,详细解析了Jackson库中BeanDeserializer的反序列化过程,包括如何处理各种JSON令牌,以及StringDeserializer和BooleanDeserializer的具体实现。
910

被折叠的 条评论
为什么被折叠?



