Skip to content

Commit d885656

Browse files
committed
Automatically detect class to deserialize FasterXML#5064
1 parent 6fb591c commit d885656

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java

+26
Original file line numberDiff line numberDiff line change
@@ -3055,6 +3055,23 @@ public <T> T readValue(JsonParser p, Class<T> valueType)
30553055
return (T) _readValue(getDeserializationConfig(), p, _typeFactory.constructType(valueType));
30563056
}
30573057

3058+
/**
3059+
* Reads the value from the given JSON content and automatically detects the class type.
3060+
*
3061+
* @param <T> the type of the object to read
3062+
* @param p the JsonParser
3063+
* @param reified don't pass any values here. It's a trick to detect the class type.
3064+
* @return the deserialized object
3065+
* @throws JsonProcessingException if there is a problem processing the JSON
3066+
*/
3067+
public <T> T readValue(JsonParser p, T... reified) throws IOException {
3068+
if (reified.length > 0) {
3069+
throw new IllegalArgumentException("Please don't pass any values here. Java will detect class automatically.");
3070+
}
3071+
3072+
return readValue(p, _typeFactory.constructType(getClassOf(reified)));
3073+
}
3074+
30583075
/**
30593076
* Method to deserialize JSON content into a Java type, reference
30603077
* to which is passed as argument. Type is passed using so-called
@@ -3985,6 +4002,15 @@ public <T> T readValue(byte[] src, int offset, int len,
39854002
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueType));
39864003
}
39874004

4005+
@SuppressWarnings("unchecked")
4006+
public <T> T readValue(byte[] src, int offset, int len, T... reified) throws IOException {
4007+
if (reified.length > 0) {
4008+
throw new IllegalArgumentException("Please don't pass any values here. Java will detect class automatically.");
4009+
}
4010+
4011+
return readValue(src, offset, len, _typeFactory.constructType(getClassOf(reified)));
4012+
}
4013+
39884014
@SuppressWarnings({ "unchecked" })
39894015
public <T> T readValue(byte[] src, TypeReference<T> valueTypeRef)
39904016
throws IOException, StreamReadException, DatabindException

src/test/java/com/fasterxml/jackson/databind/BoundsChecksForInputTest.java

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public void testBoundsWithByteArrayInput() throws Exception {
4545
final JavaType TYPE = MAPPER.constructType(String.class);
4646
_testBoundsWithByteArrayInput(
4747
(data,offset,len)->MAPPER.readValue(data, offset, len, TYPE));
48+
49+
_testBoundsWithByteArrayInput(
50+
(data,offset,len)->MAPPER.readValue(data, offset, len));
4851
}
4952

5053
private void _testBoundsWithByteArrayInput(ByteBackedCreation creator) throws Exception

src/test/java/com/fasterxml/jackson/databind/deser/JacksonTypesDeserTest.java

+44
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,50 @@ public void testTokenBufferWithSample() throws Exception
8282
}
8383
}
8484

85+
@Test
86+
public void testTokenBufferWithSequenceWithAutoDetectClass() throws Exception
87+
{
88+
final ObjectMapper mapper = jsonMapperBuilder()
89+
.disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
90+
.build();
91+
92+
// and then sequence of other things
93+
JsonParser p = mapper.createParser("[ 32, [ 1 ], \"abc\", { \"a\" : true } ]");
94+
assertToken(JsonToken.START_ARRAY, p.nextToken());
95+
96+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
97+
TokenBuffer buf = mapper.readValue(p);
98+
99+
// check manually...
100+
JsonParser bufParser = buf.asParser();
101+
assertToken(JsonToken.VALUE_NUMBER_INT, bufParser.nextToken());
102+
assertEquals(32, bufParser.getIntValue());
103+
assertNull(bufParser.nextToken());
104+
105+
// then bind to another
106+
buf = mapper.readValue(p);
107+
bufParser = buf.asParser();
108+
assertToken(JsonToken.START_ARRAY, bufParser.nextToken());
109+
assertToken(JsonToken.VALUE_NUMBER_INT, bufParser.nextToken());
110+
assertEquals(1, bufParser.getIntValue());
111+
assertToken(JsonToken.END_ARRAY, bufParser.nextToken());
112+
assertNull(bufParser.nextToken());
113+
114+
// third one, with automatic binding
115+
buf = mapper.readValue(p);
116+
String str = mapper.readValue(buf.asParser());
117+
assertEquals("abc", str);
118+
119+
// and ditto for last one
120+
buf = mapper.readValue(p, TokenBuffer.class);
121+
Map<?,?> map = mapper.readValue(buf.asParser());
122+
assertEquals(1, map.size());
123+
assertEquals(Boolean.TRUE, map.get("a"));
124+
125+
assertEquals(JsonToken.END_ARRAY, p.nextToken());
126+
assertNull(p.nextToken());
127+
}
128+
85129
@SuppressWarnings("resource")
86130
@Test
87131
public void testTokenBufferWithSequence() throws Exception

0 commit comments

Comments
 (0)