Сериализатор Джексона назвал неправильные типы - PullRequest
0 голосов
/ 08 мая 2018

Я работаю с Джексоном и написал следующий специальный сериализатор:

public class FooSerializer extends StdSerializer<List<Foo>> {

  public FooSerializer() {
    this(null);
  }

  public FooSerializer(Class<List<Foo>> t) {
    super(t);
  }

  public void serialize(List<Foo> foos, JsonGenerator gen, SerializerProvider provider) throws IOException {
    gen.writeStartArray(foos.size());
    for(Foo foo : foos){
        gen.writeString(foo.getName());
    }
    gen.writeEndArray();
  }
}

Я зарегистрировал его в ObjectMapper следующим образом:

SimpleModule fooModule = new SimpleModule("Foo Module");
fooModule.addSerializer(new FooSerializer((Class<List<Foo>>)(Object)List.class));
objectMapper.registerModule(fooModule);

Я ожидаю, что он возьмет объект с List из Foo с и вернет его как

{
  ...
  "foos":["name1", "name2"]
  ...
}

Это работает нормально, однако, когда я передаю List из SomeObjectHoldingFoos, каждый из которых имеет List из Foo, ObjectMapper пытается применить FooSerializer к этому List уже, в результате чего Foo cannot be cast to SomeObjectHoldingFoos Исключение.

Я подозреваю, что handledType из FooSerializer каким-то образом был установлен как List вместо List<Foo>, но я не знаю, как это исправить, поскольку, похоже, нет класса для параметризованного тип.

Что я могу сделать?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Я понял, что мне просто нужно Converter, а не Serializer, я реализовал следующее:

public class FooConverter extends StdConverter<Foo, String> {

  @Override
  public String convert(Foo value) {
    return value.getName();
  }

  public static SimpleModule getSimpleModule(){
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(Foo.class, new StdDelegatingSerializer(new FooConverter()));
    return simpleModule;
  }
}

и я зарегистрировал его следующим образом:

SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(TAGWrapper.class, new StdDelegatingSerializer(new TagWrapperConverter()));
objectMapper.registerModule()
0 голосов
/ 08 мая 2018

Используйте JavaType вместо Class.

class FooSerializer extends StdSerializer<List<Foo>> {

    FooSerializer(JavaType javaType) {
        super(javaType);
    }

    ....
}

И зарегистрируйте, как показано ниже:

SimpleModule fooModule = new SimpleModule("Foo Module");
CollectionLikeType type = mapper.getTypeFactory().constructCollectionLikeType(ArrayList.class, Foo.class);
fooModule.addSerializer(new FooSerializer(type));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...