java - Jackson 为同一类提供多个 ObjectMapper

标签 java json serialization jackson jackson-modules

我想在不同的资源方法中使用两个映射器序列化相同的类别类。
我编写了两个类,以两种不同的方式序列化类别 CategorySerializedCategoryTreeSerialized

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

这是类别资源

@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 序列化。
但是,如果在我调用 /categories 资源之后始终使用 CategoryTreeSerialized 类而不是 CategorySerialized

进行序列化

(反之亦然)

最佳答案

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

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

关于java - Jackson 为同一类提供多个 ObjectMapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45263953/

相关文章:

java - StackTraceElement类中的getLineNumber()方法如何查找java源文件的实际行号

Java FutureTask 异常

c++ - 我如何在 C++ 中将 vector 序列化为 char,以便轻松使用 mongodb 作为后端

json - PHP7、JSON 和 Zend(解码失败 : syntax error)

c# - 关闭/忽略 xsd 代码生成中指定的字段后缀

java - 使用 writeReplace 进行 Corba 编码和代理

java - 在android中提取xml标签之间的字符串而不解析xml

java - 保存页面站点

javascript - JSON 中的数组中的数组

asp.net - 有奇怪的 {"d":null} in JSON response