CategoryTreeSerialized

CategoryTreeSerialized

我想在不同的资源方法中使用两个映射器序列化同一Category类。
我编写了两个以两种不同方式序列化Category的类
CategorySerialized和CategoryTreeSerialized

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)));


不幸的是,这不起作用,因为mapper是静态final。
第一个调用的资源,注册模块,然后不更改

例如,如果我首先调用/ categoriestree资源,则会得到CategoryTreeSerialized序列化。
但是,如果在我调用之后/ categories资源始终使用CategoryTreeSerialized类而不是CategorySerialized进行序列化

(反之亦然)

最佳答案

不知道这是否可能是Spring MVC,我的示例是针对JAX-RS的,但是通过谷歌搜索,您应该找到类似的解决方案。
您可以为每个Response返回一个Request,其中主体使用相应的序列化器进行序列化,例如:

@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();
}

10-08 15:03