Skip to content

Commit d338aa5

Browse files
committed
Fixed #349
1 parent 152f855 commit d338aa5

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Project: jackson-databind
66

77
2.8.6 (not yet released)
88

9+
#349: @JsonAnySetter with @JsonUnwrapped: deserialization fails with arrays
10+
(reported by hdave@github)
911
#1388: `@JsonIdentityInfo`: id has to be the first key in deserialization when
1012
deserializing with `@JsonCreator`
1113
(reported by moodysalem@github)

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java

+56-15
Original file line numberDiff line numberDiff line change
@@ -632,13 +632,24 @@ protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext c
632632
handleIgnoredProperty(p, ctxt, bean, propName);
633633
continue;
634634
}
635-
// but... others should be passed to unwrapped property deserializers
636-
tokens.writeFieldName(propName);
637-
tokens.copyCurrentStructure(p);
635+
// 29-Nov-2016, tatu: probably should try to avoid sending content
636+
// both to any setter AND buffer... but, for now, the only thing
637+
// we can do.
638638
// how about any setter? We'll get copies but...
639-
if (_anySetter != null) {
639+
if (_anySetter == null) {
640+
// but... others should be passed to unwrapped property deserializers
641+
tokens.writeFieldName(propName);
642+
tokens.copyCurrentStructure(p);
643+
} else {
644+
// Need to copy to a separate buffer first
645+
TokenBuffer b2 = new TokenBuffer(p, ctxt);
646+
b2.copyCurrentStructure(p);
647+
tokens.writeFieldName(propName);
648+
tokens.append(b2);
640649
try {
641-
_anySetter.deserializeAndSet(p, ctxt, bean, propName);
650+
JsonParser p2 = b2.asParser(p);
651+
p2.nextToken();
652+
_anySetter.deserializeAndSet(p2, ctxt, bean, propName);
642653
} catch (Exception e) {
643654
wrapAndThrow(e, bean, propName, ctxt);
644655
}
@@ -681,12 +692,28 @@ protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext c
681692
handleIgnoredProperty(p, ctxt, bean, propName);
682693
continue;
683694
}
684-
// but... others should be passed to unwrapped property deserializers
685-
tokens.writeFieldName(propName);
686-
tokens.copyCurrentStructure(p);
695+
// 29-Nov-2016, tatu: probably should try to avoid sending content
696+
// both to any setter AND buffer... but, for now, the only thing
697+
// we can do.
687698
// how about any setter? We'll get copies but...
688-
if (_anySetter != null) {
689-
_anySetter.deserializeAndSet(p, ctxt, bean, propName);
699+
if (_anySetter == null) {
700+
// but... others should be passed to unwrapped property deserializers
701+
tokens.writeFieldName(propName);
702+
tokens.copyCurrentStructure(p);
703+
} else {
704+
// Need to copy to a separate buffer first
705+
TokenBuffer b2 = new TokenBuffer(p, ctxt);
706+
b2.copyCurrentStructure(p);
707+
tokens.writeFieldName(propName);
708+
tokens.append(b2);
709+
try {
710+
JsonParser p2 = b2.asParser(p);
711+
p2.nextToken();
712+
_anySetter.deserializeAndSet(p2, ctxt, bean, propName);
713+
} catch (Exception e) {
714+
wrapAndThrow(e, bean, propName, ctxt);
715+
}
716+
continue;
690717
}
691718
}
692719
tokens.writeEndObject();
@@ -755,15 +782,29 @@ protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser p, Deseri
755782
handleIgnoredProperty(p, ctxt, handledType(), propName);
756783
continue;
757784
}
758-
tokens.writeFieldName(propName);
759-
tokens.copyCurrentStructure(p);
760-
// "any property"?
761-
if (_anySetter != null) {
785+
// 29-Nov-2016, tatu: probably should try to avoid sending content
786+
// both to any setter AND buffer... but, for now, the only thing
787+
// we can do.
788+
// how about any setter? We'll get copies but...
789+
if (_anySetter == null) {
790+
// but... others should be passed to unwrapped property deserializers
791+
tokens.writeFieldName(propName);
792+
tokens.copyCurrentStructure(p);
793+
} else {
794+
// Need to copy to a separate buffer first
795+
TokenBuffer b2 = new TokenBuffer(p, ctxt);
796+
b2.copyCurrentStructure(p);
797+
tokens.writeFieldName(propName);
798+
tokens.append(b2);
762799
try {
763-
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
800+
JsonParser p2 = b2.asParser(p);
801+
p2.nextToken();
802+
buffer.bufferAnyProperty(_anySetter, propName,
803+
_anySetter.deserialize(p2, ctxt));
764804
} catch (Exception e) {
765805
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
766806
}
807+
continue;
767808
}
768809
}
769810

src/main/java/com/fasterxml/jackson/databind/deser/impl/UnwrappedPropertyHandler.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ public UnwrappedPropertyHandler renameAll(NameTransformer transformer)
5151
}
5252

5353
@SuppressWarnings("resource")
54-
public Object processUnwrapped(JsonParser originalParser, DeserializationContext ctxt, Object bean,
55-
TokenBuffer buffered)
56-
throws IOException, JsonProcessingException
54+
public Object processUnwrapped(JsonParser originalParser, DeserializationContext ctxt,
55+
Object bean, TokenBuffer buffered)
56+
throws IOException
5757
{
5858
for (int i = 0, len = _properties.size(); i < len; ++i) {
5959
SettableBeanProperty prop = _properties.get(i);
60-
JsonParser jp = buffered.asParser();
61-
jp.nextToken();
62-
prop.deserializeAndSet(jp, ctxt, bean);
60+
JsonParser p = buffered.asParser();
61+
p.nextToken();
62+
prop.deserializeAndSet(p, ctxt, bean);
6363
}
6464
return bean;
6565
}

src/test/java/com/fasterxml/jackson/failing/AnySetter349Test.java renamed to src/test/java/com/fasterxml/jackson/databind/deser/AnySetter349Test.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.failing;
1+
package com.fasterxml.jackson.databind.deser;
22

33
import java.util.*;
44

@@ -26,7 +26,7 @@ public Map<String, Object> getProperties() {
2626
}
2727

2828
@JsonUnwrapped
29-
public IdentityDTO349 identity = null;
29+
public IdentityDTO349 identity;
3030
}
3131

3232
static class IdentityDTO349 {
@@ -38,9 +38,9 @@ public void testUnwrappedWithAny() throws Exception
3838
final ObjectMapper mapper = objectMapper();
3939
final String json = aposToQuotes(
4040
"{ 'type' : 'IST',\n"
41-
+" 'spacename' : 'Foo Models',\n"
42-
+" 'name' : 'BLAH-New',\n"
43-
+" 'description' : 'namespace.name: X THIN FIR.DR-WD12-New',\n"
41+
//+" 'spacename' : 'Foo Models',\n"
42+
//+" 'name' : 'BLAH-New',\n"
43+
//+" 'description' : 'namespace.name: X THIN FIR.DR-WD12-New',\n"
4444
+" 'ZoomLinks': [ 'foofoofoofoo', 'barbarbarbar' ] }"
4545
);
4646
Bean349 value = mapper.readValue(json, Bean349.class);

0 commit comments

Comments
 (0)