0
votes

I am writing a Spring WebFlux route in Kotlin to handle POST requests with a JSON body. However, after sending my cURL request, I can see that the ServerRequest object has basically nothing in it, certainly not the JSON I sent.

curl -v -X POST -H "Content-Type: application/json" -d '{"key1":"value1","key2":"value2"}' http://myserver:8989/query

SearchServerConfig.kt

@Configuration
open class SearchServerConfig {

    @Bean
    open fun searchServer(): ISearchServer {
        return SearchServer()
    }

    @Bean
    open fun route(searchServer: ISearchServer): RouterFunction<ServerResponse?> {
        return RouterFunctions.route(
            RequestPredicates.POST("/query").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)).and(RequestPredicates.contentType(MediaType.APPLICATION_JSON)),
            HandlerFunction { request: ServerRequest? -> searchServer.performQuery(request)!!
            })
    }
}

SearchServer.kt

open class SearchServer() : ISearchServerService {
    companion object {
        val logger = LoggerFactory.getLogger(SearchServer::class.java)
    }

    override fun performQuery(request: ServerRequest?): Mono<ServerResponse?>? {
        logger.debug("!!>> request=[$request]")
        ...
}

This log output from the logs only contains:

!!>> request=[HTTP POST /query]

So obviously, when I try to extract the JSON body

val bodyData: String = request?.bodyToMono(JSONObject::class.java)?.toProcessor()?.peek()!!.toString()

it throws a NPE. Why is there no body from the cURL request present, or any of the headers, or anything really?

1

1 Answers

0
votes

Posting in case its useful to anyone else at some point.

Issue was further down the line, even though nothing gave me any indication of a mapping issue with the body, not even IntelliJ's debugger. It just seemed to ignore it completely with the only issue being the NPE.

In searchServer.performQuery() I was trying to extract the body to a Jackson ObjectNode.

val bodyData: String = request?.bodyToMono(ObjectNode::class.java)?.toProcessor()?.peek()!!.toString()

Changing to going straight to String like this and subscribed to the Mono, that it worked.

val bodyData = request?.bodyToMono(String::class.java)?.subscribe{ logger.info("Body", it) }