Binding from Multiple Bindable values
Instead of binding just query values, it is also possible to bind any Bindable value to a POJO (e.g. to bind HttpRequest
, @PathVariable
, @QueryValue
and @Header
to a single POJO). This can be achieved with the @RequestBean
annotation and a custom Bean class with fields with Bindable annotations, or fields that can be bound by type (e.g. HttpRequest
, BasicAuth
, Authentication
, etc.).
For example:
Binding Bindable values to POJO
@Controller("/api")
public class MovieTicketController {
// You can also omit query parameters like:
// @Get("/movie/ticket/{movieId}
@Get("/movie/ticket/{movieId}{?minPrice,maxPrice}")
public HttpStatus list(@Valid @RequestBean MovieTicketBean bean) {
return HttpStatus.OK;
}
}
Binding Bindable values to POJO
@Controller("/api")
class MovieTicketController {
// You can also omit query parameters like:
// @Get("/movie/ticket/{movieId}
@Get("/movie/ticket/{movieId}{?minPrice,maxPrice}")
HttpStatus list(@Valid @RequestBean MovieTicketBean bean) {
HttpStatus.OK
}
}
Binding Bindable values to POJO
@Controller("/api")
open class MovieTicketController {
// You can also omit query parameters like:
// @Get("/movie/ticket/{movieId}
@Get("/movie/ticket/{movieId}{?minPrice,maxPrice}")
open fun list(@Valid @RequestBean bean: MovieTicketBean): HttpStatus {
return HttpStatus.OK
}
}
which uses this bean class:
Bean definition
@Introspected
public class MovieTicketBean {
private HttpRequest<?> httpRequest;
@PathVariable
private String movieId;
@Nullable
@QueryValue
@PositiveOrZero
private Double minPrice;
@Nullable
@QueryValue
@PositiveOrZero
private Double maxPrice;
public MovieTicketBean(HttpRequest<?> httpRequest,
String movieId,
Double minPrice,
Double maxPrice) {
this.httpRequest = httpRequest;
this.movieId = movieId;
this.minPrice = minPrice;
this.maxPrice = maxPrice;
}
public HttpRequest<?> getHttpRequest() {
return httpRequest;
}
public String getMovieId() {
return movieId;
}
@Nullable
public Double getMaxPrice() {
return maxPrice;
}
@Nullable
public Double getMinPrice() {
return minPrice;
}
}
Bean definition
@Introspected
class MovieTicketBean {
private HttpRequest<?> httpRequest
@PathVariable
String movieId
@Nullable
@QueryValue
@PositiveOrZero
Double minPrice
@Nullable
@QueryValue
@PositiveOrZero
Double maxPrice
}
Bean definition
@Introspected
data class MovieTicketBean(
val httpRequest: HttpRequest<Any>,
@field:PathVariable val movieId: String,
@field:QueryValue @field:PositiveOrZero @field:Nullable val minPrice: Double,
@field:QueryValue @field:PositiveOrZero @field:Nullable val maxPrice: Double
)
The bean class has to be introspected with @Introspected
. It can be one of:
Mutable Bean class with setters and getters
Immutable Bean class with getters and an all-argument constructor (or
@Creator
annotation on a constructor or static method). Arguments of the constructor must match field names so the object can be instantiated without reflection.
Since Java does not retain argument names in bytecode, you must compile code with -parameters to use an immutable bean class from another jar. Another option is to extend Bean class in your source. |