1

I'am trying to get User object from json by Jayway JsonPath. My class is:

 public class User{
    private String id;
    private String name;
    private String password;
    private String email;
    /*getters setters constructor*/
  }

And json example:

{
  "user": [
    {
      "id": "1",
      "login": "client1",
      "password": "qwerty",
      "email": "client@gmail.com"
    }
  ]
}

I wanna to get smth like this:

public Optional<User> find(String id) throws NoSuchEntityException {
    Optional<User> user = Optional.empty();
    try{
        Path path = Path.of(fileDestination+fileName);
        ReadContext ctx = JsonPath.parse(Files.readString(path));
        User readUser = ctx.read("$..user[*]",User.class,Filter.filter(where("id").is(id)));
        user = Optional.ofNullable(readUser);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return user;
}

Or to get good advice how to code it:D

  • Glad I could help. I noticed you never accepted or upvoted an answer, please follow: https://stackoverflow.com/help/someone-answers & https://stackoverflow.com/tour – wp78de Jul 29 '21 at 17:06

1 Answers1

1

two things here

  1. you must use the placeholder ? instead of * when you're filtering, otherwise, the filter will be ignored.
  2. read() will return a list, not a single object.

so, I think, you need something like this

String json = "{\r\n"
        + "  \"user\": [\r\n"
        + "    {\r\n"
        + "      \"id\": \"1\",\r\n"
        + "      \"login\": \"client1\",\r\n"
        + "      \"password\": \"qwerty\",\r\n"
        + "      \"email\": \"client@gmail.com\"\r\n"
        + "    }\r\n"
        + "  ]\r\n"
        + "}";

Predicate filterById = filter(where("id").is("1"));
List<User> users = JsonPath.parse(json).read("$.user[?]",filterById );

System.out.println(users);

Reference: Filter Predicates

where("category").is("fiction").and("price").lte(10D) );

List<Map<String, Object>> books =     
parse(json).read("$.store.book[?]", cheapFictionFilter); 

Notice the placeholder ? for the filter in the path. When multiple filters are provided they are applied in order where the number of placeholders must match the number of provided filters. You can specify multiple predicate placeholders in one filter operation [?, ?], both predicates must match.

wp78de
  • 18,207
  • 7
  • 43
  • 71
shikida
  • 485
  • 2
  • 10
  • `$.user[?]` isn't valid JSON Path syntax. Is this actually supported by Jayway? What does it do? – gregsdennis Jun 27 '21 at 00:40
  • 1
    Found it: https://github.com/json-path/JsonPath see "Filter Predicates". Looks like it's a mechanism employed by this library that functions similarly to string interpolation, but for injecting filters defined elsewhere. – gregsdennis Jun 27 '21 at 00:44
  • Yes, the placeholder `?` works similar to a bind param in an SQL query. – wp78de Jun 29 '21 at 16:06