10

複数の設定を使用したシリアライゼーション/デシリアライゼーションのためにJacksonを使用してJerseyをセットアップすることは可能ObjectMappersですか?

私ができるようにしたいのは、「デフォルト」のジャクソンを登録してから、特定の状況下で「デフォルト」を「オーバーライド」する特殊な構成をObjectMapper提供する別の機能を登録する機能です。ObjectMapperObjectMapper

たとえば、これContextResolverは「デフォルト」マッパーの場合です。

@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
    private final ObjectMapper mObjectMapper;

    public JacksonMapperProvider() {
        mObjectMapper = createMapper();
    }

    protected abstract ObjectMapper createMapper() {
        ObjectMapper mapper = createMapper();

        return mapper
            .setSerializationInclusion(Include.ALWAYS)
            .configure(JsonParser.Feature.ALLOW_COMMENTS, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
            .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mObjectMapper;
    }
}

そして、これContextResolverは「デフォルト」マッパーをオーバーライドすることです:

@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class SpecializedMapperProvider implements ContextResolver<ObjectMapper> {
    private final ObjectMapper mObjectMapper;

    public SpecializedMapperProvider() {
        mObjectMapper = createMapper();
    }

    protected abstract ObjectMapper createMapper() {
        ObjectMapper mapper = createMapper();

        return mapper
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
            .registerModule(new SpecializedModule1())
            .registerModule(new SpecializedModule2());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        if(SomeType.isAssignableFrom(type)) {
            return mObjectMapper;
        }
        return null;
    }
}

JacksonJsonProviderJackson がObjectMapperプロバイダーの注入/解決をサポートしているコードが表示されます。ただし、実際には、プロバイダーの「順序」がランダムに見えます (そうではないと思いますが、順序を制御する方法を整理することはできません)。「オーバーライド」が「デフォルト」の前に来て、すべてが機能する場合がありますが、次のサーバーの起動時に順序が変更されます。

私はこれを次のようなさまざまな方法で機能させようとしました。

  • 実装を手動で登録するContextResolver<ObjectMapper>(異なる順序で)
  • アノテーションContextResolver<ObjectMapper>による実装の登録@Provider
  • 登録時の優先度指定

私は以下を使用しています:

  • ジャージー 2.8
  • ジャクソン 2.3.3

おそらく私は完全に間違ったアプローチを取っていますか?
私がやろうとしていることを達成するためのより良い方法はありますか? 2 つの別個の JAX-RS アプリケーションを定義し、それぞれに 1 つの ObjectMapper 構成を設定するだけでよいでしょうか?

4

2 に答える 2

3

プロバイダーの順序を構成できますが、実際には、この状況では 1 つのプロバイダーを使用するのが最善です。

@Provider
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
    private final ObjectMapper defaultMapper;
    private final ObjectMapper specializedMapper;

    public JacksonMapperProvider() {
        defaultMapper = createDefaultMapper();
        specializedMapper = createSpecializedMapper();
    }

    private static ObjectMapper createDefaultMapper() {
        return new ObjectMapper()
            .setSerializationInclusion(Include.ALWAYS)
            .configure(JsonParser.Feature.ALLOW_COMMENTS, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
            .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
    }

    private static ObjectMapper createSpecializedMapper() {
        return new ObjectMapper()
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
            .registerModule(new SpecializedModule1())
            .registerModule(new SpecializedModule2());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        if (SomeType.isAssignableFrom(type)) {
            return specializedMapper;
        }
        else {
            return defaultMapper;
        }
    }
}
于 2014-05-12T21:52:30.133 に答える
0

一番新しい方法は

new ObjectMapper().configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

jackson の最近のバージョンで ALLOW_UNQUOTED_FIELD_NAMES を取得します。

于 2019-12-16T01:06:59.497 に答える