【问题标题】:Jackson in Jersey with multiple Serializers for one Entity泽西岛的杰克逊为一个实体提供多个序列化器
【发布时间】:2015-02-07 16:39:49
【问题描述】:

我正在使用 Jersey 2.11 和 Jackson 2.4.0 实现 REST 后端以进行序列化。 我的实体如下所示:

public class Measurement {

public Measurement() {
    super();
}

private Long id;
private Double lat;
private Double lon;
private Long timestamp;
private User owner;
}

在某些响应中,我希望将此实体序列化为 GeoJSON,而在其他响应中,将其序列化为带有 User.id 而不是 User 对象的 Measurement。因此,我编写了两个自定义 JsonSerializer,并将它们注册到我的 ObjectMapperResolver 类中。

@Provider
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {

private final ObjectMapper defaultMapper;
private final ObjectMapper geojsonMapper;

public ObjectMapperResolver() {
    defaultMapper = createDefaultMapper();
    geojsonMapper = createGeojsonMapper();
}

private static ObjectMapper createDefaultMapper() {
    SimpleModule module = new SimpleModule();
    module.addSerializer(Measurement.class, new MeasurementSerializer());

    return new ObjectMapper()
    .enable(SerializationFeature.INDENT_OUTPUT)
    .registerModule(module);
}

private static ObjectMapper createGeojsonMapper() {
    SimpleModule module = new SimpleModule();
    module.addSerializer(Measurement.class, new GeoJSONSerializer());

    return new ObjectMapper()
    .enable(SerializationFeature.INDENT_OUTPUT)
    .registerModule(module);
}

@Override
public ObjectMapper getContext(Class<?> type) {
    if (type.equals(Measurement.class)) {
        return geojsonMapper;
    }
    else {
        return defaultMapper;
    }
}

}

在当前设置中,每当测量被序列化时,其序列化为 GeoJSON。每当我的其他实体(确实包含测量)被序列化时,都会使用 defaultMapper。 我需要为单个实体类 (Measurement.class) 切换序列化器/映射器的可能性

最好的问候!

【问题讨论】:

  • 如果您可以为不同的格式设置不同的媒体类型,则很容易实现。
  • 不幸的是,我的 Angular 前端更喜欢只处理 JSON。

标签: java json serialization jersey jackson


【解决方案1】:

这是我在 Spring 应用程序中所做的: 1. 创建了我的 CustomObjectMapper 类。 2. 创建类特定的 json 生成器方法。 3. 在控制器中自动装配所需的对象映射器。

映射器1:

public class CustomObjectMapper1 extends ObjectMapper {
    public CustomObjectMapper1() {
        super();
        super.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        super.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        super.setDateFormat(df);
    }
    public byte[] generateJson(Object value) throws IOException, JsonGenerationException, JsonMappingException {
        Hibernate4Module hm = new Hibernate4Module();
        hm.configure(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION, false);
        hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
        return super.registerModule(hm).writeValueAsBytes(value);
    }
}

映射器2:

public class CustomObjectMapper2 extends ObjectMapper {
    public CustomObjectMapper2() {
        super();
        super.setDateFormat(df);
    }
    public byte[] generateJson(Object value) throws IOException, JsonGenerationException, JsonMappingException {
        Hibernate4Module hm = new Hibernate4Module();
        return super.registerModule(hm).writeValueAsBytes(value);
    }
}

在控制器中:

...
byte[] json = customObjectMapper1.generateJson(myObject);
return json;

...
byte[] json = customObjectMapper2.generateJson(myObject);
return json;

希望对你有帮助。

【讨论】:

  • 谢谢,我喜欢您的解决方案,并且可能会使用它。唯一的缺点是每个响应都必须手动序列化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 2014-08-10
  • 2016-05-02
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多