2017-07-23 67 views
1

我想序列化與兩個映射器在不同的資源方法相同的類別類。
我寫了兩種不同的方式 CategorySerializedCategoryTreeSerialized傑克遜提供程序同一類的多個ObjectMapper

public class MyJacksonJsonProvider implements ContextResolver<ObjectMapper> 
{ 
    private static final ObjectMapper MAPPER = new ObjectMapper(); 

    static { 
     MAPPER.enable(SerializationFeature.INDENT_OUTPUT);   
     MAPPER.registerModule(new SimpleModule() 
       .addSerializer(Category.class, new CategorySerializer(Category.class))); 
     } 

    public MyJacksonJsonProvider() { 
     System.out.println("Instantiate MyJacksonJsonProvider"); 
    } 

    @Override 
    public ObjectMapper getContext(Class<?> type) { 
     System.out.println("MyJacksonProvider.getContext() called with type: "+type); 
     return MAPPER; 
    } 

系列化分類兩大類,這是簡單的實體分類

@Entity 
    public class Category { 

     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 

     @Type(type = "objectid") 
     private String id; 
     private String name; 

     @ManyToOne 
     @JsonManagedReference 
     private Category parent; 

     @JsonBackReference 
     @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER) 
     @Column(insertable = false) 
     private List<Category> children; 

     ....getter and setter .... 
    } 

這是CategoryResource

@Path(value = "resource") 
public class CategoryResource { 

    @Inject 
    CategoryService categoryService; 

    @Context 
    Providers providers; 

    @GET 
    @Produces(value = MediaType.APPLICATION_JSON+";charset="+ CharEncoding.UTF_8) 
    @Path("/categories") 
    public List getCategories(){ 
     List<Category> categories = categoryService.findAll(); 
     return categories; 
    } 

    @GET 
    @Produces(value = MediaType.APPLICATION_JSON+";charset="+ CharEncoding.UTF_8) 
    @Path("/categoriestree") 
    public List getCategoriesTree(){ 
     List<Category> categories = categoryService.findAll(); 

     ContextResolver<ObjectMapper> cr = providers 
       .getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE); 
     ObjectMapper c = cr.getContext(ObjectMapper.class); 
     c.registerModule(new SimpleModule() 
       .addSerializer(Category.class, new CategoryTreeSerializer(Category.class))); 

     return categories; 
    } 

CategorySerialized延伸StdSerializer登記與提供

MAPPER.registerModule(new SimpleModule() 
        .addSerializer(Category.class, new CategorySerializer(Category.class))); 

CategoryTreeSerialized延伸StdSerializer註冊的資源

ContextResolver<ObjectMapper> cr = providers 
        .getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE); 
      ObjectMapper c = cr.getContext(ObjectMapper.class); 
      c.registerModule(new SimpleModule() 
        .addSerializer(Category.class, new CategoryTreeSerializer(Category.class))); 

內不幸的是,這並不工作,因爲映射是靜態的決賽。
所謂的第一資源,註冊模塊,然後不改變

例如,如果我稱之爲/categoriestree資源第一,我得到CategoryTreeSerialized系列化。
但是,如果以後我叫/類別資源總是與CategoryTreeSerialized類序列化,而不是與CategorySerialized

(反之亦然)

+0

有道理。你有什麼問題? – shmosel

+0

我想,當我打電話** getCategories **(/類別)我得到序列化** CategorySerialized **,當我打電話** getCategoryTree **(/ categoriestree)我得到序列化** CategoryTreeSerialized ** – Pako

+0

所以使用不同的映射器。 – shmosel

回答

1

不知道這可能是Spring MVC的,我的例子適用於JAX-RS,但使用谷歌搜索你應該找到一個類似的解決方案。

@GET 
@Produces(value = MediaType.APPLICATION_JSON+";charset="+ CharEncoding.UTF_8) 
@Path("/categories") 
public Response getCategories(){ 
    List<Category> categories = categoryService.findAll(); 
    ResponseBuilder response = ResponseBuilder.ok() 
      .entity(new MyCategoriesMapper() 
       .build(categories)) 
      .type(MediaType.APPLICATION_JSON)); 

    return response.build(); 
} 

@GET 
@Produces(value = MediaType.APPLICATION_JSON+";charset="+ CharEncoding.UTF_8) 
@Path("/categoriestree") 
public Response getCategoriesTree(){ 
    List<Category> categories = categoryService.findAll(); 
    ResponseBuilder response = ResponseBuilder.ok() 
      .entity(new MyCategoriesTreeMapper() 
       .build(categories)) 
      .type(MediaType.APPLICATION_JSON)); 

    return response.build(); 
} 
0

我發現的唯一的解決方案是創建一個包裝類,使範疇類的副本和: 你可以爲每個Request,在身體與相應的串行連載中一樣返回Response註冊

我已經創建了一個名爲CategoryTree類別實體的副本是實體 的精確副本,我註冊了CategoryTreeSerialized系列化CategoryTree模塊該模塊

@Provider 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class MyJacksonJsonProvider implements ContextResolver<ObjectMapper> 
{ 
    private static final ObjectMapper MAPPER_DEFAULT = new ObjectMapper(); 


    static { 
     MAPPER_DEFAULT.enable(SerializationFeature.INDENT_OUTPUT); 
     MAPPER_DEFAULT.registerModule(new SimpleModule() 
      .addSerializer(Category.class, new CategorySerializer(Category.class))); 
     MAPPER_DEFAULT.registerModule(new SimpleModule() 
      .addSerializer(CategoryTree.class, new CategoryTreeSerializer(CategoryTree.class))); 

    public MyJacksonJsonProvider() { 
     System.out.println("Instantiate MyJacksonJsonProvider"); 
    } 

    @Override 
    public ObjectMapper getContext(Class<?> type) { 
     System.out.println("MyJacksonProvider.getContext() called with 
     return MAPPER_DEFAULT; 
    } 
} 

在CategoryResource類,我得到轉化爲列出清單副本

@GET 
@Produces(value = MediaType.APPLICATION_JSON+";charset="+ CharEncoding.UTF_8) 
@Path("/categoriestree") 
public List getCategoriesTree(){ 
    List<Category> categories = categoryService.findAll(); 

    List<CategoryTree> categoryTrees = 
      new CategoryTree().createList(categories); 
    return categoryTrees; 
} 

然後CategoryTree是
類別 副本這個解決方案不是很表演和優雅,但它是唯一一個作品,因爲它無法註銷模塊

如果有人有不同,表演和優雅的解決方案寫下來