3

I have a simple User class:

public class User {
    private long id;
    private String username;
    private String password;
    private String someCommonData;
    private String someAdminData;
}

I would like to have different representations of that User in json. A version for normal users:

{"username":"myName", "someCommonData":"bla"}

and a representation for adminUsers:

{"id":1, "username":"myName", "someCommonData":"bla", "someAdminData":"don't show this to the user!"}

When I use @JsonIgnore then it is always ignored but I would like to have conditional ignore.

The only solution that would work so far is to have two different classes. Isn't there a more beautiful solution?

Packo
  • 43
  • 5

2 Answers2

2

Take a look at @JsonView

public class User {
    @JsonView({Admin.class})
    private long id;

    @JsonView({Basic.class})
    private String username;

    @JsonIgnore
    private String password;

    @JsonView({Basic.class})
    private String someCommonData;

    @JsonView({Admin.class})
    private String someAdminData;

    static class Basic {
    }

    static class Admin extends Basic {
    }

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();


        User user = new User();
        user.id = 1L;
        user.username = "admin";
        user.password = "nimda";
        user.someCommonData = "common-data";
        user.someAdminData = "admin-data";

        ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();

        System.out.println(writer.withView(Basic.class).writeValueAsString(user));
        System.out.println(writer.withView(Admin.class).writeValueAsString(user));
    }
}

output of main:

{
  "username" : "admin",
  "someCommonData" : "common-data"
}
{
  "id" : 1,
  "username" : "admin",
  "someCommonData" : "common-data",
  "someAdminData" : "admin-data"
}

This blog explains the basics: http://www.baeldung.com/jackson-json-view-annotation

Pieter
  • 2,745
  • 14
  • 17
  • This comes very close to what I was searching for. Only point that is not that good is that using JsonView forces me to annotate all fields of the class. I haven't found something to include the fields without JsonView annotation. – Packo Aug 02 '16 at 07:42
  • To include non annotated fields you have to enable DEFAULT_VIEW_INCLUSION. In Spring Boot/MVC applications just add `spring.jackson.mapper.default-view-inclusion=true` to your application.properties. – Packo Aug 02 '16 at 08:34
0

The best and easest aproach I can figure out is to use two classses. Sorry. But it looks for me like a better design when you do this:

public class User {
    private long id;
    private String username;
    private String password;
    private String someCommonData;
}

public class Admin extends User {
    private String someAdminData;
}
Rene M.
  • 2,660
  • 15
  • 24
  • In some scenarios I do agree that this may be the cleaner solution. But when the class gets larger you have to maintain a larger codebase which I want to avoid. – Packo Aug 02 '16 at 07:13