Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JSON BodyHandlers/BodyPublishers support for the new Java 11 HttpClient #45

Open
pragmasoft-ua opened this issue Jan 7, 2020 · 7 comments

Comments

@pragmasoft-ua
Copy link

Similar to the described in this SO thread

https://stackoverflow.com/questions/57629401/deserializing-json-using-java-11-httpclient-and-custom-bodyhandler-with-jackson

@cowtowncoder
Copy link
Member

I am not quite sure of the part that relates to Jackson here... could you elaborate?

@sergeykad
Copy link

sergeykad commented Jan 3, 2021

BodyHandler that can convert raw InputStream with JSON into a POJO.
BodyPublisher that takes a POJO and converts it into a byte array with JSON.

In other words Java 11 HTTP client integration.

@cowtowncoder
Copy link
Member

This sounds like some kind of extension module (jackson-jr has couple, for example; and there are JAX-RS providers) or package, then, at least initially. Databind cannot have dependency to Java 11 quite yet.

@davinkevin
Copy link

Small up because with all evolutions in Java 17 and 21 now, just using Jackson with the java client is something I do a lot, in addition with native compilation to get something simple & performant.

@cowtowncoder
Copy link
Member

As usual, PRs welcome!
Could perhaps be added to jackson-modules-base or something. Does not belong to core (jackson-core, jackson-databind) components

@JooHyukKim
Copy link
Member

Would be great if someone can share solid usage example tho... like to what extent this "new module" should incorporate HttpClient ?

@davinkevin
Copy link

davinkevin commented Nov 22, 2023

I did that in Kotlin:

class JsonBody {
    companion object {
        val defaultObjectMapper = ObjectMapper().findAndRegisterModules()!!

        fun publisher(body: Any, objectMapper: ObjectMapper? = null): BodyPublisher {
            val mapper = objectMapper ?: this.defaultObjectMapper
            return BodyPublishers.ofString(mapper.writeValueAsString(body))
        }

        inline fun <reified T> handler(objectMapper: ObjectMapper? = null): BodyHandler<T> {
            val mapper = objectMapper ?: this.defaultObjectMapper
            val jsonNodeSubscriber = BodySubscribers.mapping(BodySubscribers.ofByteArray()) {
                mapper.readValue(it, T::class.java)
            }
            return BodyHandler { jsonNodeSubscriber }
        }
    }
}

And usage is very simple:

val request = HttpRequest.newBuilder()
            .uri(URI.create(instance.spec.url.toASCIIString() + "/api/v2/links"))
            .POST(JsonBody.publisher(linkBody))
            .header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
            .header("Authorization", token)
            .build()

return client.send(request, JsonBody.handler<LinkCreationResult>()).body()

It's part of a POC… I kept the opportunity to provide the ObjectMapper as parameter, but the companion has a default one too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants