'@JsonView on Spring @GetMapping query parameter objects
In Spring, is it possible to use @JsonView
on URL query parameter objects? I can do it for @RequestBody
but we don't have bodies in GET requests. This question is specifically for URL query parameters that have been converted to objects by Spring.
For example, I want to have a controller with this mapping:
@GetMapping("/user")
ResponseEntity<UserDTO> searchUser(@JsonView(value = UserView.Searchable.class) UserDTO userQuery) {
//Do some work here using userQuery object for searching users
return ResponseEntity.ok();
}
UserDTO
:
public class UserDTO {
@JsonProperty("id")
@JsonView(UserView.Private.class)
private String id= null;
@JsonView(UserView.Searchable.class)
@JsonProperty("city")
private String city = null;
@JsonProperty("country")
@JsonView(UserView.Searchable.class)
private String country = null;
@JsonProperty("state")
private String state = null;
@JsonProperty("zipCode")
private String zipCode = null;
//More properties and getter/setters...etc
}
So if I wanted to call the endpoint I could create a URL like
localhost:8080//api/user?country=Canada
to search for a user in Canada but if I tried localhost:8080//api/user?id=123
, the property would be ignored.
EDIT:
I might have rushed this idea. There is no JSON de-serialization from url parameters because they are not JSON. Spring creates the query object from ServletModelAttributeMethodProcessor
. Perhaps if I want some custom behavior I need to implement HandlerMethodArgumentResolver
and do it myself.
EDIT 2
I'm a bit new to Spring so I have a lot to learn but I think what Ill do is just use @InitBinder
to whitelist the fields for binding
@InitBinder
public void setSearchableFields(WebDataBinder binder) {
binder.setAllowedFields(
"city",
"country"
);
}
Solution 1:[1]
In one of my projects, I have used a POJO just for the query params. I doubt any property would be ignored by default in spring, you can have null checks to ignore.
QueryParams.java
@Data
public class QueryParams {
Integer page;
Integer pageSize;
String sortBy;
Sort.Direction direction;
String searchId;
String status;
String symbol;
public PageRequest getPageRequest(){
if(this.page==null){
this.page = 0;
}
if(this.pageSize==null){
this.pageSize = 25;
}
if(this.sortBy==null){
this.sortBy = "createdAt";
}
if(this.direction ==null){
this.direction = Sort.Direction.DESC;
}
return PageRequest.of(this.page, this.pageSize, Sort.by(this.direction, this.sortBy));
}
}
And my controller :
@GetMapping("currencies")
public ResponseEntity<Page<CurrencyConfig>> getAllCurrencies(@Valid QueryParams queryParams) {
try {
return ResponseEntity.ok(orderbookService.getAllCurrencyConfig(queryParams));
} catch (HttpClientErrorException | HttpServerErrorException e) {
throw new ResponseStatusException(e.getStatusCode(), e.getMessage());
} catch (Exception e) {
e.printStackTrace();
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR,
e.getLocalizedMessage());
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dharman |