Closed erkieh closed 4 months ago
This issue seems to be related to this issue except for that
Please note that any default values in Kotlin data classes are ignored during deserialization in this issue.
A possible workaround for returning 400 bad request when Long-value is missing in JSON, may be to use @Min
along with @Bindable
annotations (given that only non-negative numbers are valid):
import io.micronaut.core.bind.annotation.Bindable
import io.micronaut.serde.annotation.Serdeable
import jakarta.validation.constraints.Min
@Serdeable
data class NonNullDto(
@Min(0L)
@Bindable(defaultValue = "-1")
val longField: Long
)
Tests
import com.deserializenull.rest.dto.NonNullDto
import com.deserializenull.rest.dto.NullDto
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest
@MicronautTest
class NonNullDtoControllerTest(
@Client("/") httpClient: HttpClient
) : StringSpec({
"test deserialization with null data, expect 400 response" {
val exception = shouldThrow<HttpClientResponseException> {
httpClient.toBlocking().exchange(HttpRequest.POST("/nonnulldto", NullDto()), NullDto::class.java)
}
exception.status.code shouldBe 400
}
"test deserialization with valid data, expect 200 response" {
val response = httpClient.toBlocking().exchange(HttpRequest.POST("/nonnulldto", NonNullDto(longField = 1)), NonNullDto::class.java)
val responseBody = response.getBody(NonNullDto::class.java).get()
response.status.code shouldBe 200
responseBody.longField shouldBe 1
}
})
Please create / update the sample app with your use case
The behaviour is the same as a default in Jackson. The fix is a configuration to fail on null primitives.
Expected Behavior
Posting validated HTTP JSON Payloads with missing values for Non-nullable Long Kotlin data class fields should result in a 400 bad request response,
Actual Behaviour
Non-nullable Long Kotlin data class fields are initialized with 0 when the field is missing in the payload. Strings for example behave differently. They don't get defaulted. Instead the result will be an 500 Internal server error with a NullPointerException happening on the server side.
Steps To Reproduce
Run tests in sample app
Environment Information
Windows 10 Java 21
Example Application
git@github.com:erkieh/demonullhandling.git
Version
4.5.0-SNAPSHOT