Reputation: 45
I'm trying to implement json serialization of the single entity to different views according to used interface. For example we have:
public interface BookBrief {
long getId();
String getTitle();
}
public interface BookPreview {
long getId();
String getAnnotation();
}
public class Book implements BookBrief, BookPreview {
// class fields here
public long getId() {...}
public String getTitle() {...}
public String getText() {...}
public String getAnnotation() {...}
// setters here
}
// service which results is serialized to json in Spring MVC controllers
public interface BookService {
List<? extends BookBrief> getBooks();
BookPreview getBookPreview(long id);
Book getBook(long id);
}
BookService implementation always returns Book class (with unused fields set to null). To serialize interfaces I tried to use annotation @JsonSerialize(as = Interface.class) for each, but for all interfaces jackson always use only the first one listed in 'implements' expression. Is there a way to configure jackson like I need? Or may be there is a better solution?
Upvotes: 2
Views: 2561
Reputation: 5542
Seems like you have 2 options:
With Views it could be implemented in 3 easy steps:
BookViews.java:
public class BookViews {
public static class BookBrief { }
public static class BookPreview { }
}
Book.java:
public class Book {
@JsonView({BookViews.BookBrief.class, BookViews.BookPreview.class})
private long id;
@JsonView(BookViews.BookBrief.class)
private String title;
@JsonView(BookViews.BookPreview.class)
private String annotation;
// Constructors and getters/setters
}
BookService.java:
@Path("books")
public class BookService {
private static final List<Book> library = Arrays.asList(
new Book(1, "War and Peace", "Novel"),
new Book(2, "A Game of Thrones", "Fantasy")
);
@GET
@Path("all")
@JsonView(BookViews.BookBrief.class)
@Produces(MediaType.APPLICATION_JSON)
public Response getBooks() {
return Response.status(Response.Status.OK).entity(library).build();
}
@GET
@Path("previews")
@JsonView(BookViews.BookPreview.class)
@Produces(MediaType.APPLICATION_JSON)
public Response getBookPreviews() {
return Response.status(Response.Status.OK).entity(library).build();
}
}
Result:
GET http://localhost:8080/root/rest/books/all:
[
{
"id": 1,
"title": "War and Peace"
},
{
"id": 2,
"title": "A Game of Thrones"
}
]
GET http://localhost:8080/root/rest/books/previews:
[
{
"annotation": "Novel",
"id": 1
},
{
"annotation": "Fantasy",
"id": 2
}
]
Upvotes: 3