Skip to content

Commit 40701f1

Browse files
committed
Add Object-to-Scalar support for some String/String-like types
1 parent 7b9e7dd commit 40701f1

File tree

2 files changed

+48
-34
lines changed

2 files changed

+48
-34
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java

+44-34
Original file line numberDiff line numberDiff line change
@@ -142,33 +142,49 @@ public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOExcepti
142142
{
143143
// Let's get textual value, possibly via coercion from other scalar types
144144
String text = p.getValueAsString();
145-
if (text != null) { // has String representation
146-
if (text.length() == 0 || (text = text.trim()).length() == 0) {
147-
// 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well
148-
return (T) _deserializeFromEmptyString(ctxt);
145+
if (text == null) {
146+
JsonToken t = p.currentToken();
147+
if (t != JsonToken.START_OBJECT) {
148+
return (T) _deserializeFromOther(p, ctxt, t);
149149
}
150-
Exception cause = null;
151-
try {
152-
// 19-May-2017, tatu: Used to require non-null result (assuming `null`
153-
// indicated error; but that seems wrong. Should be able to return
154-
// `null` as value.
155-
return _deserialize(text, ctxt);
156-
} catch (IllegalArgumentException | MalformedURLException e) {
157-
cause = e;
158-
}
159-
// note: `cause` can't be null
160-
String msg = "not a valid textual representation";
161-
String m2 = cause.getMessage();
162-
if (m2 != null) {
163-
msg = msg + ", problem: "+m2;
164-
}
165-
// 05-May-2016, tatu: Unlike most usage, this seems legit, so...
166-
JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg);
167-
e.initCause(cause);
168-
throw e;
169-
// nothing to do here, yet? We'll fail anyway
150+
// 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
151+
text = ctxt.extractScalarFromObject(p, this, _valueClass);
152+
}
153+
if (text.length() == 0 || (text = text.trim()).length() == 0) {
154+
// 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well
155+
return (T) _deserializeFromEmptyString(ctxt);
156+
}
157+
Exception cause = null;
158+
try {
159+
// 19-May-2017, tatu: Used to require non-null result (assuming `null`
160+
// indicated error; but that seems wrong. Should be able to return
161+
// `null` as value.
162+
return _deserialize(text, ctxt);
163+
} catch (IllegalArgumentException | MalformedURLException e) {
164+
cause = e;
165+
}
166+
// note: `cause` can't be null
167+
String msg = "not a valid textual representation";
168+
String m2 = cause.getMessage();
169+
if (m2 != null) {
170+
msg = msg + ", problem: "+m2;
170171
}
171-
JsonToken t = p.currentToken();
172+
// 05-May-2016, tatu: Unlike most usage, this seems legit, so...
173+
JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg);
174+
e.initCause(cause);
175+
throw e;
176+
}
177+
178+
/**
179+
* Main method from trying to deserialize actual value from non-empty
180+
* String.
181+
*/
182+
protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
183+
184+
// @since 2.12
185+
protected Object _deserializeFromOther(JsonParser p, DeserializationContext ctxt,
186+
JsonToken t) throws IOException
187+
{
172188
// [databind#381]
173189
if (t == JsonToken.START_ARRAY) {
174190
return _deserializeFromArray(p, ctxt);
@@ -180,19 +196,13 @@ public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOExcepti
180196
return null;
181197
}
182198
if (_valueClass.isAssignableFrom(ob.getClass())) {
183-
return (T) ob;
199+
return ob;
184200
}
185-
return (T) _deserializeEmbedded(ob, ctxt);
201+
return _deserializeEmbedded(ob, ctxt);
186202
}
187-
return (T) ctxt.handleUnexpectedToken(_valueClass, p);
203+
return ctxt.handleUnexpectedToken(_valueClass, p);
188204
}
189205

190-
/**
191-
* Main method from trying to deserialize actual value from non-empty
192-
* String.
193-
*/
194-
protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
195-
196206
/**
197207
* Overridable method to allow coercion from embedded value that is neither
198208
* {@code null} nor directly assignable to target type.

src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
5757
// otherwise, try conversion using toString()...
5858
return ob.toString();
5959
}
60+
// 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
61+
if (t == JsonToken.START_OBJECT) {
62+
return ctxt.extractScalarFromObject(p, this, _valueClass);
63+
}
6064
// allow coercions for other scalar types
6165
// 17-Jan-2018, tatu: Related to [databind#1853] avoid FIELD_NAME by ensuring it's
6266
// "real" scalar

0 commit comments

Comments
 (0)