Skip to content

Commit 5dc7e21

Browse files
committed
Added mismatch check for deserialization result
1 parent a36ed39 commit 5dc7e21

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonParser
44
import com.fasterxml.jackson.core.TreeNode
55
import com.fasterxml.jackson.core.type.TypeReference
66
import com.fasterxml.jackson.databind.JsonDeserializer
7+
import com.fasterxml.jackson.databind.JsonMappingException
78
import com.fasterxml.jackson.databind.JsonNode
89
import com.fasterxml.jackson.databind.JsonSerializer
910
import com.fasterxml.jackson.databind.MappingIterator
@@ -50,20 +51,44 @@ fun ObjectMapper.registerKotlinModule(initializer: KotlinModule.Builder.() -> Un
5051

5152
inline fun <reified T> jacksonTypeRef(): TypeReference<T> = object: TypeReference<T>() {}
5253

54+
/**
55+
* It is public due to Kotlin restrictions, but should not be used externally.
56+
*/
57+
inline fun <reified T> Any?.checkTypeMismatch(): T {
58+
// Basically, this check assumes that T is non-null and the value is null.
59+
// Since this can be caused by both input or ObjectMapper implementation errors,
60+
// a more abstract JsonMappingException is thrown.
61+
if (this !is T) {
62+
throw JsonMappingException(
63+
null,
64+
"Deserialized value did not match the specified type; " +
65+
"specified ${T::class.qualifiedName} but was ${this?.let { it::class.qualifiedName }}"
66+
)
67+
}
68+
return this
69+
}
70+
5371
inline fun <reified T> ObjectMapper.readValue(jp: JsonParser): T = readValue(jp, jacksonTypeRef<T>())
72+
.checkTypeMismatch()
5473
inline fun <reified T> ObjectMapper.readValues(jp: JsonParser): MappingIterator<T> = readValues(jp, jacksonTypeRef<T>())
5574

56-
inline fun <reified T> ObjectMapper.readValue(src: File): T = readValue(src, jacksonTypeRef<T>())
57-
inline fun <reified T> ObjectMapper.readValue(src: URL): T = readValue(src, jacksonTypeRef<T>())
75+
inline fun <reified T> ObjectMapper.readValue(src: File): T = readValue(src, jacksonTypeRef<T>()).checkTypeMismatch()
76+
inline fun <reified T> ObjectMapper.readValue(src: URL): T = readValue(src, jacksonTypeRef<T>()).checkTypeMismatch()
5877
inline fun <reified T> ObjectMapper.readValue(content: String): T = readValue(content, jacksonTypeRef<T>())
59-
inline fun <reified T> ObjectMapper.readValue(src: Reader): T = readValue(src, jacksonTypeRef<T>())
78+
.checkTypeMismatch()
79+
inline fun <reified T> ObjectMapper.readValue(src: Reader): T = readValue(src, jacksonTypeRef<T>()).checkTypeMismatch()
6080
inline fun <reified T> ObjectMapper.readValue(src: InputStream): T = readValue(src, jacksonTypeRef<T>())
81+
.checkTypeMismatch()
6182
inline fun <reified T> ObjectMapper.readValue(src: ByteArray): T = readValue(src, jacksonTypeRef<T>())
83+
.checkTypeMismatch()
6284

6385
inline fun <reified T> ObjectMapper.treeToValue(n: TreeNode): T = readValue(this.treeAsTokens(n), jacksonTypeRef<T>())
86+
.checkTypeMismatch()
6487
inline fun <reified T> ObjectMapper.convertValue(from: Any?): T = convertValue(from, jacksonTypeRef<T>())
88+
.checkTypeMismatch()
6589

6690
inline fun <reified T> ObjectReader.readValueTyped(jp: JsonParser): T = readValue(jp, jacksonTypeRef<T>())
91+
.checkTypeMismatch()
6792
inline fun <reified T> ObjectReader.readValuesTyped(jp: JsonParser): Iterator<T> = readValues(jp, jacksonTypeRef<T>())
6893
inline fun <reified T> ObjectReader.treeToValue(n: TreeNode): T? = readValue(this.treeAsTokens(n), jacksonTypeRef<T>())
6994

0 commit comments

Comments
 (0)