'@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