wasabifx/wasabi

Improving application/json support

pijusn opened this issue · 2 comments

I am not sure whether it's true elsewhere but most developers I know use use JSON requests in all new projects. This makes it very important for HTTP server library to supports it very well.

However, Wasabi only handles string values. Accessing value of any other type causes an exception:

DEBUG org.wasabi.http.NettyRequestHandler - Exception during web invocation: java.lang.Integer cannot be cast to java.lang.String
DEBUG org.wasabi.http.NettyRequestHandler - Exception during web invocation: java.lang.Boolean cannot be cast to java.lang.String
DEBUG org.wasabi.http.NettyRequestHandler - Exception during web invocation: java.lang.Double cannot be cast to java.lang.String
DEBUG org.wasabi.http.NettyRequestHandler - Exception during web invocation: java.util.ArrayList cannot be cast to java.lang.String
DEBUG org.wasabi.http.NettyRequestHandler - Exception during web invocation: java.util.LinkedHashMap cannot be cast to java.lang.String

That's because JsonDeserializer works like this:

override fun deserialize(input: Any): HashMap<String, String> {
    val mapper = ObjectMapper()
    val map = mapper.readValue(input as String, javaClass<HashMap<String, String>>())!!
    return map
}

Because of type erasure Jackson parses it to HashMap<Object, Object> but Wasabi still treats it as HashMap<String, String>.

Even though application/json request can have an array as the body ([ 1, 2, 3 ]), that's a simple problem to work around on both ends (and in most cases you want to have a wrapper object for a better flexibility anyway). Let's only consider request with objects as the body ({"name": "value"}).

I suggest using Map<String, Any?> as it is the simplest solution and it is quite expressive:

val username = request.bodyParams["username"] as String
val rememberMe = request.bodyParams["remember_me"] as Boolean

Casts can also be hidden using Delegates.mapVal in most cases.

I'm OK with this. In fact this and some other things were kind of a "work in progress". Would you like to send a PR?

I could easily make the change. It will take a couple of days (quite busy at the moment).