Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 3655

I'd like to know how I could use Dynamic Filtering (with MappingJacksonValue) and implement HATEOS (EntityModel) for my particular REST API?

$
0
0

So I have been learning REST API with Spring Boot

I have a User bean

@JsonFilter("UserFilter")public class User {    private int id;    @Size(min = 2, message = "Name should have at least 2 characters")    private String name;    @JsonProperty("Birth Date")    @Past(message = "Birth date should be in the past")    private LocalDate birthDate;    public User(int id, String name, LocalDate birthDate) {        this.id = id;        this.name = name;        this.birthDate = birthDate;    }    @Override    public String toString() {        return "User{" +"id=" + id +", name='" + name +'\''+", birth=" + birthDate +'}';    }}

and I have a UserDao to access User data

@Componentpublic class UserDaoService {    private static List<User> users = new ArrayList<>();    static {        users.add(new User(1, "Alice", LocalDate.now()                .minusYears(18)                .minusMonths(1)));        users.add(new User(2, "Bob", LocalDate.now()                .minusYears(21)                .plusMonths(3)                .plusDays(5)));        users.add(new User(3, "Cathy", LocalDate.now()                .minusDays(7)                .minusYears(25)));        users.add(new User(4, "David", LocalDate.now()                .minusYears(23)));    }    public List<User> findAll() {        return users;    }    public User findById(int id) {        return users.stream()                .filter(user -> user.getId() == id)                .findFirst()                .orElse(null);    }}

I also have a UserController where I map Endpoints/Requests to REST API responses.

@RestControllerpublic class UserController {    private UserDaoService service;    public UserController(UserDaoService service) {        this.service = service;    }    @GetMapping("/users")    public MappingJacksonValue findAllUsers() {        List<User> usersList = service.findAll();        MappingJacksonValue mjv = new MappingJacksonValue(usersList);        SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept("name", "Birth Date");        FilterProvider filters = new SimpleFilterProvider().addFilter("UserFilter", filter);        mjv.setFilters(filters);        return mjv;    }    @GetMapping("/users/{id}")    public EntityModel<User> findUserById(@PathVariable int id) {        User usr = service.findById(id);        if (usr == null)            throw new UserNotFoundException("id:" + id);        EntityModel<User> model = EntityModel.of(usr);        WebMvcLinkBuilder link = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(this.getClass()).findAllUsers());        model.add(link.withRel("all-users"));        return model;    }}

For the findAllUsers() method I tried to make use of dynamic filtering using MappingJacksonValue. For findUserById() method I don't want to apply any filtering but I do want to add a link to the full list of users (using EntityModel) when a person views details on a single user.

When I make a GET request to localhost:8080/users/3 I get the following error:HttpMessageConversionException: type definition error: [simple type, class SpringBootFramwork.RESTAPI.beans.User]caused by InvalidDefinitionException: Cannot resolve PropertyFilter with id 'UserFilter'; no FilterProvider configured (through reference chain: org.springframework.hateoas.EntityModel["content"])

It seems when I comment out the @JsonFilter annotation from the User bean the GET request works, but of course no filtering when I GET localhost:8080/users (retrieve all of the users). Why is it when I add the @JsonFilter annotation to my User bean I get the above error? How can I fix this?

Expected Response:{"id": 3,"name": "Cathy","Birth Date": "1999-04-19","_links": {"all-users": {"href": "http://localhost:8080/users"}}}


Viewing all articles
Browse latest Browse all 3655

Trending Articles