quarkus: Cannot deserialize LocalDate in @QueryParam due to missing ParamConverterProvider
Describe the bug
I’m using Jackson (via quarkus-resteasy-jackson) as ObjectMapper
with the KotlinModule
and the JavaTimeModule
registered using an ObjectMapperCustomizer
. When I have an endpoint with a @QueryParam
of type LocalDate
quarkus does not start.
Expected behavior
I expect resteasy to use the provided ObjectMapper
to deserialize a String formated “YYYY-MM-DD” into an instance of LocalDate
.
Actual behavior Omitting the name and method signature for brevity I get
RESTEASY003875: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam("adate") for basetype: java.time.LocalDate
To Reproduce Steps to reproduce the behavior:
- Use
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
- Register a resource like
@GET
@Path("path")
fun broken( @QueryParam("adate") aDate: LocalDate) {}
- Run a
@QuarkusTest
to try a start up the application.
Environment (please complete the following information):
- Output of
uname -a
orver
: Linux ninja-cgd 5.3.0-23-generic #25-Ubuntu SMP Tue Nov 12 09:22:33 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux - Output of
java -version
: openjdk version “11.0.5-ea” 2019-10-15 OpenJDK Runtime Environment (build 11.0.5-ea+10-post-Ubuntu-0ubuntu1) OpenJDK 64-Bit Server VM (build 11.0.5-ea+10-post-Ubuntu-0ubuntu1, mixed mode, sharing) - GraalVM version (if different from Java): not used
- Quarkus version or git rev: 0.25.0 Additional context
The problem is fixed by adding
@Provider
class LocalDateConverter : ParamConverterProvider {
override fun <T: Any?> getConverter(rawType: Class<T>?, genericType: Type?, annotations: Array<out Annotation>?): ParamConverter<T>? {
return if (rawType == LocalDate::class.java) {
object: ParamConverter<T> {
val mapper = ObjectMapper().also { JacksonObjectMapperCustomizer().customize(it) }
override fun toString(value: T?): String {
return mapper.writeValueAsString(value)
}
override fun fromString(value: String?): T {
return mapper.readValue(value, LocalDate::class.java) as T
}
}
} else null
}
}
to the project. I was expecting that this kind of Provider would be added out of the box when using Jackson’s JavaTimeModule
.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 41 (33 by maintainers)
Commits related to this issue
- Add ParamConverter for LocalDate fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add tests for LocalDateParamConverterProvider fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add param converter for LocalDate fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add support for LocalDate as query parameter fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add tests for LocalDate as PathParam and QueryParam fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add tests for LocalDate as PathParam and QueryParam fix #5860 — committed to belu/quarkus by deleted user 3 years ago
- Add param converter for LocalDate fix #5860 — committed to belu/quarkus by deleted user 3 years ago
@geoand The
"
is part of the JSON.2019-01-01
is invalid; it has to be"2019-01-01"
. See https://www.json.org/json-en.htmlThanks. I’ll take a look tomorrow or Friday
@geoand Yes, can do that with your help & guidance.
Well TBH it doesn’t make sense to me to have to expect the query string to contain quotes. Sure the converter could add them, but that doesn’t feel natural.
You mentioned that Spring does this as well, do you mind point me to this feature in Spring that utilizes Jackson? I wasn’t aware of it.
I have a different idea, we can just use
objectMapper.convertValue
😉 . I tried it and it see to work fine, WDYT?That way the user can just use
2019-01-01
without having to add the uggly quotes (remember that they don’t care if it’s JSON or not - it’s just a query param).Interesting, so that means that you expect users to input
"2019-01-01"
as query param?When using I do
objectMapper.readValue(value, LocalDate.class)
with2019-01-01
being the value