Kotlin - How to set values on ObjectNode?

Viewed 2022

I'm trying to create a Json object using Jackson but I can't use put because it's deprecated and will fail the pipelines checks in my company so I'm trying to use set:

fun HttpRequest.toJSONString(): String {
    val mapper = ObjectMapper()
    val root = mapper.createObjectNode()
    val headers = mapper.createObjectNode()

    this.headers().map().entries.forEach {h ->
        headers.put(h.key, mapper.convertValue(h.value, JsonNode::class.java)) // its deprecated
    }

    root.set("headers", headers) // its failing
    root.set("url_path", "https://facebook.com") // fails

    return root.toString()
}

I got an error message: Not enough information to infer parameter T in operator fun <T : JsonNode!> set(p0: String!, p1: JsonNode!): T! Please specify it explicitly.

How can I solve it?

2 Answers

I would advise you to try something more like that:

fun HttpRequest.toJSONString() =
  ObjectMapper().writeValueAsString(
    this.headers
      .put("url_path", listOf("https://facebook.com"))
    // put the rest here 
  )

It is usually inconvenient to deal directly with the Node objects and they are protected. I would strongly advise you to write your whole objects in kotlin and then use writeValueAsString from the ObjectMapper.

Use put when the value is a string (that version of the method is not deprecated). Use replace when the value is a JsonNode, or, if you want to chain the invocations together use set with a type parameter. Code to demonstrate:

    val mapper = ObjectMapper()
    val root = mapper.createObjectNode()
    val headers = mapper.createObjectNode()

    headers.put("key", "value") // Use put when the value is a primitive

    root.replace("headers", headers) // Use replace for objects
    root.set<JsonNode>("headers", headers) // Or use set with a type parameter
    root.put("url_path", "https://facebook.com")

    return root.toString()
Related