diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-29 17:09:42 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-29 17:09:42 -0700 |
commit | 40701f15a81c1f2ed7aae2a43173f97ab7403af9 (patch) | |
tree | 1089c78bf1cfde4cd782ba393048112ce2603478 /src/main/java | |
parent | 7b9e7ddec3722b4b97dff76d41b3cbaa4685e577 (diff) | |
download | jackson-databind-40701f15a81c1f2ed7aae2a43173f97ab7403af9.tar.gz |
Add Object-to-Scalar support for some String/String-like types
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java | 78 | ||||
-rw-r--r-- | src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java | 4 |
2 files changed, 48 insertions, 34 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java index a750550b4..52e52832d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java @@ -142,33 +142,49 @@ public abstract class FromStringDeserializer<T> extends StdScalarDeserializer<T> { // Let's get textual value, possibly via coercion from other scalar types String text = p.getValueAsString(); - if (text != null) { // has String representation - if (text.length() == 0 || (text = text.trim()).length() == 0) { - // 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well - return (T) _deserializeFromEmptyString(ctxt); + if (text == null) { + JsonToken t = p.currentToken(); + if (t != JsonToken.START_OBJECT) { + return (T) _deserializeFromOther(p, ctxt, t); } - Exception cause = null; - try { - // 19-May-2017, tatu: Used to require non-null result (assuming `null` - // indicated error; but that seems wrong. Should be able to return - // `null` as value. - return _deserialize(text, ctxt); - } catch (IllegalArgumentException | MalformedURLException e) { - cause = e; - } - // note: `cause` can't be null - String msg = "not a valid textual representation"; - String m2 = cause.getMessage(); - if (m2 != null) { - msg = msg + ", problem: "+m2; - } - // 05-May-2016, tatu: Unlike most usage, this seems legit, so... - JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg); - e.initCause(cause); - throw e; - // nothing to do here, yet? We'll fail anyway + // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML) + text = ctxt.extractScalarFromObject(p, this, _valueClass); + } + if (text.length() == 0 || (text = text.trim()).length() == 0) { + // 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well + return (T) _deserializeFromEmptyString(ctxt); + } + Exception cause = null; + try { + // 19-May-2017, tatu: Used to require non-null result (assuming `null` + // indicated error; but that seems wrong. Should be able to return + // `null` as value. + return _deserialize(text, ctxt); + } catch (IllegalArgumentException | MalformedURLException e) { + cause = e; + } + // note: `cause` can't be null + String msg = "not a valid textual representation"; + String m2 = cause.getMessage(); + if (m2 != null) { + msg = msg + ", problem: "+m2; } - JsonToken t = p.currentToken(); + // 05-May-2016, tatu: Unlike most usage, this seems legit, so... + JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg); + e.initCause(cause); + throw e; + } + + /** + * Main method from trying to deserialize actual value from non-empty + * String. + */ + protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException; + + // @since 2.12 + protected Object _deserializeFromOther(JsonParser p, DeserializationContext ctxt, + JsonToken t) throws IOException + { // [databind#381] if (t == JsonToken.START_ARRAY) { return _deserializeFromArray(p, ctxt); @@ -180,20 +196,14 @@ public abstract class FromStringDeserializer<T> extends StdScalarDeserializer<T> return null; } if (_valueClass.isAssignableFrom(ob.getClass())) { - return (T) ob; + return ob; } - return (T) _deserializeEmbedded(ob, ctxt); + return _deserializeEmbedded(ob, ctxt); } - return (T) ctxt.handleUnexpectedToken(_valueClass, p); + return ctxt.handleUnexpectedToken(_valueClass, p); } /** - * Main method from trying to deserialize actual value from non-empty - * String. - */ - protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException; - - /** * Overridable method to allow coercion from embedded value that is neither * {@code null} nor directly assignable to target type. * Used, for example, by {@link UUIDDeserializer} to coerce from {@code byte[]}. diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java index 41850051a..2cdf67a1d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java @@ -57,6 +57,10 @@ public class StringDeserializer extends StdScalarDeserializer<String> // non-fin // otherwise, try conversion using toString()... return ob.toString(); } + // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML) + if (t == JsonToken.START_OBJECT) { + return ctxt.extractScalarFromObject(p, this, _valueClass); + } // allow coercions for other scalar types // 17-Jan-2018, tatu: Related to [databind#1853] avoid FIELD_NAME by ensuring it's // "real" scalar |