Currently I am trying to reduce the number of parameters on @RequestMapping annotated methods in a class annotation with @RestController using kotlin data classes. Also I don't want to repeat myself on multiple @RequestMapping annotated methods which contain the same path variables.
The code below shows my approach where /multiple/ABC/true/123 works as expected but /single/ABC/true/123 complains about a missing default constructor.
data class Params(@PathVariable("param1") val param1: String,
@PathVariable("param2") val param2: Boolean,
@PathVariable("param3") val param3: Int)
@RestController
class TestController {
@RequestMapping("/single/{param1}/{param2}/{param3}")
fun single(params: Params) {
println(listOf(params.param1, params.param2, params.param3))
}
@RequestMapping("/multiple/{param1}/{param2}/{param3}")
fun multiple(@PathVariable("param1") param1: String,
@PathVariable("param2") param2: Boolean,
@PathVariable("param3") param3: Int) {
println(listOf(param1, param2, param3))
}
}
When I use the following data class definition instead I get a result but then the instance isn't immutable anymore and may have some fields not updated.
data class Params(@PathVariable("param1") var param1: String = "",
@PathVariable("param2") var param2: Boolean = false,
@PathVariable("param3") var param3: Int = 0)
Can anyone help me making the first data class definition work?
You can't really do that since Spring won't invoke constructors apart from the default constructor.
Another problem is that you can only bind individual path variables to objects so you can't create a complex object this way.
I'd stick with the version which uses vars since it works properly and create an immutable object after you receive the request.
Another option is to pass a json object as a parameter because Jackson has more thorough support for this kind of deserialization or you can write a deserializer by hand.