2015-08-21 108 views
0

我試圖根據使用的接口實現單個實體的json序列化到不同的視圖。 例如,我們有:傑克遜和多接口繼承

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的實現總是返回書類(設置爲null未使用的字段)。 爲了序列化接口,我試圖對每個使用註釋@JsonSerialize(as = Interface.class),但對於所有接口,jackson總是隻使用'實現'表達式中列出的第一個接口。 有沒有像我需要配置jackson的方法?或者可能有更好的解決方案?

回答

1

好像你有2種選擇:

  1. 編寫自定義傑克遜串行
  2. 使用傑克遜的觀點,它看起來像一個更可行的選擇(完整的文檔可以發現here)。

隨着查看它可以在3個簡單的步驟來實現:

  1. 定義視圖標記:

BookViews.java

public class BookViews { 

    public static class BookBrief { } 

    public static class BookPreview { } 

} 
  1. 標註其在每個視圖中露出要預訂字段:

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 
} 
  • 標註REST方法與JSonValue和指定哪些查看您想使用:
  • 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(); 
        } 
    
    } 
    

    結果

    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 
        } 
    ]