Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 使用jackson模块kotlin反序列化泛型类_Generics_Kotlin_Jackson - Fatal编程技术网

Generics 使用jackson模块kotlin反序列化泛型类

Generics 使用jackson模块kotlin反序列化泛型类,generics,kotlin,jackson,Generics,Kotlin,Jackson,我正在尝试使用jackson kotlin集成。大多数情况下,它工作得很好,但我在反序列化泛型类型方面遇到了麻烦。我试着调整这个问题的答案: 显然,kotlin的jackson插件无法处理此问题。是否有解决方法或其他方法 顺便说一句,stringify函数是我为ObjectMapper添加的一个简单扩展函数,它负责处理样板代码: /** * Serializes [value] to a string. Pretty prints if [pretty] is set. */ fun <

我正在尝试使用jackson kotlin集成。大多数情况下,它工作得很好,但我在反序列化泛型类型方面遇到了麻烦。我试着调整这个问题的答案:

显然,kotlin的jackson插件无法处理此问题。是否有解决方法或其他方法

顺便说一句,stringify函数是我为ObjectMapper添加的一个简单扩展函数,它负责处理样板代码:

/**
 * Serializes [value] to a string. Pretty prints if [pretty] is set.
 */
fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
    val bos = ByteArrayOutputStream()
    val writer = OutputStreamWriter(bos, StandardCharsets.UTF_8)
    if(pretty) {
        writerWithDefaultPrettyPrinter().writeValue(writer,value)
    } else {
        writeValue(writer, value)
    }
    writer.flush()
    bos.flush()
    return bos.toByteArray().toString(StandardCharsets.UTF_8)
}
/**
*将[value]序列化为字符串。如果设置了[Pretty],则显示Pretty打印。
*/
stringify(值:T,pretty:Boolean=false):String{
val bos=ByteArrayOutputStream()
val writer=OutputStreamWriter(bos,StandardCharset.UTF_8)
如果(漂亮){
writerWithDefaultPrettyPrinter().writeValue(writer,值)
}否则{
writeValue(writer,value)
}
writer.flush()
bos.flush()
返回bos.toByteArray().toString(StandardCharsets.UTF_8)
}

更新@jayson minard回答中的代码。事实证明,我的代码的关键区别在于我在测试方法中定义了数据类。把它们移到顶层可以解决问题。在函数中加入一个数据类一开始就不是一个好主意。

使用Jackson的
2.9.6
,然后使用Jackson的主分支
2.9.8
,以及当前的Jackson Kotlin模块,我添加了这个测试用例,它通过了您的代码版本和更干净的代码惯用版本

请注意,我还将
stringify
方法更新为更加惯用的方法,但这不会影响测试

您对
readValue
的调用也比必要的调用复杂得多。更改:

val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
val parsed=objectMapper.readValue(序列化的objectMapper.typeFactory.ConstructParameterType(外部::class.java,内部::class.java))
简单地说:

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    
val parsed=objectMapper.readValue(序列化)
这是完全通过测试:

class TestStackOverflow53499407 {
    data class Inner(val meaningOfLife: Int)
    data class Outer<T>(val inner: T)

    fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
        StringWriter().use { writer ->
            if (pretty) {
                writerWithDefaultPrettyPrinter().writeValue(writer, value)
            } else {
                writeValue(writer, value)
            }
            return writer.toString()
        }
    }

    @Test
    fun test53499407_cleanTest() {
        val outer = Outer(Inner(42))
        val objectMapper = jacksonObjectMapper()

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
        assertEquals(42, parsed.inner.meaningOfLife)
    }

    @Test
    fun test53499407_idiomatic_tweek() {
        val outer = Outer(Inner(42))

        val jsonFactory = JsonFactory()
        jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
        jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

        val objectMapper = ObjectMapper(jsonFactory)
        objectMapper.findAndRegisterModules()
        objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        // This line changed to be idiomatic
        val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
        assertEquals(42, parsed.inner.meaningOfLife)
    }

    @Test
    fun test53499407_as_written_in_stackoverflow() {
        val outer = Outer(Inner(42))

        val jsonFactory = JsonFactory()
        jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
        jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

        val objectMapper = ObjectMapper(jsonFactory)
        objectMapper.findAndRegisterModules()
        objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        // deserializing does not work using:
        // https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
        val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
        assertEquals(42, parsed.inner.meaningOfLife)
    }
}
类TestStackOverflow53499407{
数据类内部(val意味着飞行:Int)
数据类外部(val内部:T)
stringify(值:T,pretty:Boolean=false):String{
StringWriter()。请使用{writer->
如果(漂亮){
writerWithDefaultPrettyPrinter().writeValue(writer,值)
}否则{
writeValue(writer,value)
}
return writer.toString()
}
}
@试验
趣味测试53499407_cleanTest(){
val外部=外部(内部(42))
val objectMapper=jacksonObjectMapper()
val serialized=objectMapper.stringify(外部,true)
println(序列化)
val parsed=objectMapper.readValue(序列化)
assertEquals(42,已解析。内部。表示飞行)
}
@试验
趣味测试53499407_惯用_tweek(){
val外部=外部(内部(42))
val jsonFactory=jsonFactory()
配置(JsonGenerator.Feature.AUTO\u CLOSE\u目标,false)
configure(JsonParser.Feature.IGNORE_未定义,true)
val objectMapper=objectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.PropertyNamegstrategy=PropertyNamegstrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
val serialized=objectMapper.stringify(外部,true)
println(序列化)
//这句话变成了惯用语
val parsed=objectMapper.readValue(序列化)
assertEquals(42,已解析。内部。表示飞行)
}
@试验
有趣的测试53499407_如_stackoverflow()中所述{
val外部=外部(内部(42))
val jsonFactory=jsonFactory()
配置(JsonGenerator.Feature.AUTO\u CLOSE\u目标,false)
configure(JsonParser.Feature.IGNORE_未定义,true)
val objectMapper=objectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.PropertyNamegstrategy=PropertyNamegstrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
val serialized=objectMapper.stringify(外部,true)
println(序列化)
//使用以下命令反序列化不起作用:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed=objectMapper.readValue(序列化的objectMapper.typeFactory.ConstructParameterType(外部::class.java,内部::class.java))
assertEquals(42,已解析。内部。表示飞行)
}
}

使用Jackson的
2.9.6
,然后使用Jackson的主分支
2.9.8
以及当前的Jackson Kotlin模块,我添加了这个测试用例,它通过了您的代码版本和更干净的代码惯用版本

请注意,我还将
stringify
方法更新为更加惯用的方法,但这不会影响测试

您对
readValue
的调用也比必要的调用复杂得多。更改:

val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
val parsed=objectMapper.readValue(序列化的objectMapper.typeFactory.ConstructParameterType(外部::class.java,内部::class.java))
简单地说:

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    
val parsed=objectMapper.readValue(序列化)
这是完全通过测试:

class TestStackOverflow53499407 {
    data class Inner(val meaningOfLife: Int)
    data class Outer<T>(val inner: T)

    fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
        StringWriter().use { writer ->
            if (pretty) {
                writerWithDefaultPrettyPrinter().writeValue(writer, value)
            } else {
                writeValue(writer, value)
            }
            return writer.toString()
        }
    }

    @Test
    fun test53499407_cleanTest() {
        val outer = Outer(Inner(42))
        val objectMapper = jacksonObjectMapper()

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
        assertEquals(42, parsed.inner.meaningOfLife)
    }

    @Test
    fun test53499407_idiomatic_tweek() {
        val outer = Outer(Inner(42))

        val jsonFactory = JsonFactory()
        jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
        jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

        val objectMapper = ObjectMapper(jsonFactory)
        objectMapper.findAndRegisterModules()
        objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        // This line changed to be idiomatic
        val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
        assertEquals(42, parsed.inner.meaningOfLife)
    }

    @Test
    fun test53499407_as_written_in_stackoverflow() {
        val outer = Outer(Inner(42))

        val jsonFactory = JsonFactory()
        jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
        jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

        val objectMapper = ObjectMapper(jsonFactory)
        objectMapper.findAndRegisterModules()
        objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

        val serialized = objectMapper.stringify(outer, true)
        println(serialized)

        // deserializing does not work using:
        // https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
        val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
        assertEquals(42, parsed.inner.meaningOfLife)
    }
}
类TestStackOverflow53499407{
数据类内部(val意味着飞行:Int)
数据类外部(val内部:T)
stringify(值:T,pretty:Boolean=false):String{
StringWriter()。请使用{writer->
如果(漂亮){
writerWithDefaultPrettyPrinter().writeValue(writer,值)
}否则{
writeValue(writer,value)
}
return writer.toString()
}
}
@试验
趣味测试53499407_cleanTest(){
val外部=外部(内部(42))
弗吉尼亚州