@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonParser
44import com.fasterxml.jackson.core.TreeNode
55import com.fasterxml.jackson.core.type.TypeReference
66import com.fasterxml.jackson.databind.JsonDeserializer
7+ import com.fasterxml.jackson.databind.JsonMappingException
78import com.fasterxml.jackson.databind.JsonNode
89import com.fasterxml.jackson.databind.JsonSerializer
910import com.fasterxml.jackson.databind.MappingIterator
@@ -50,20 +51,44 @@ fun ObjectMapper.registerKotlinModule(initializer: KotlinModule.Builder.() -> Un
5051
5152inline 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+
5371inline fun <reified T > ObjectMapper.readValue (jp : JsonParser ): T = readValue(jp, jacksonTypeRef<T >())
72+ .checkTypeMismatch()
5473inline 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()
5877inline 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()
6080inline fun <reified T > ObjectMapper.readValue (src : InputStream ): T = readValue(src, jacksonTypeRef<T >())
81+ .checkTypeMismatch()
6182inline fun <reified T > ObjectMapper.readValue (src : ByteArray ): T = readValue(src, jacksonTypeRef<T >())
83+ .checkTypeMismatch()
6284
6385inline fun <reified T > ObjectMapper.treeToValue (n : TreeNode ): T = readValue(this .treeAsTokens(n), jacksonTypeRef<T >())
86+ .checkTypeMismatch()
6487inline fun <reified T > ObjectMapper.convertValue (from : Any? ): T = convertValue(from, jacksonTypeRef<T >())
88+ .checkTypeMismatch()
6589
6690inline fun <reified T > ObjectReader.readValueTyped (jp : JsonParser ): T = readValue(jp, jacksonTypeRef<T >())
91+ .checkTypeMismatch()
6792inline fun <reified T > ObjectReader.readValuesTyped (jp : JsonParser ): Iterator <T > = readValues(jp, jacksonTypeRef<T >())
6893inline fun <reified T > ObjectReader.treeToValue (n : TreeNode ): T ? = readValue(this .treeAsTokens(n), jacksonTypeRef<T >())
6994
0 commit comments