Как заставить Джерси / Джексона сериализовать пустой список; один элемент списка в виде массива - PullRequest
4 голосов
/ 21 ноября 2011

Используя Джерси и Джексона для создания интерфейса REST, как получить поля списка для сериализации в виде списка, если в них 0 или 1 элемент. Например:

@XmlRootElement(name="foo")
public class Foo {
  @XmlElement
  public List<Bar> getBars() {
    return this.bars;
  }
}

@Path("foo")
public FooResource {
  @GET
  public Foo getFoo() {
    return theFoo;
  }
}

Когда у баров нет элементов, результат сериализуется как null, а когда он содержит один элемент, он сериализуется как этот элемент, а не как массив, содержащий один элемент. Есть ли способ заставить их всегда сериализовать как массив?

Для справки я использую Джерси 1.10 и Джексон 1.9.2.

Ответы [ 4 ]

4 голосов
/ 23 ноября 2011

Я почти уверен, что вы на самом деле не используете Джексона (вариант сериализации JSON "POJO"), поскольку Джексон не будет преобразовывать одноэлементные массивы или списки во что-либо еще.Таким образом, вы, вероятно, используете один из устаревших методов вывода (например, jettison);Это означает, что если вы настроите систему для использования отображения POJO, она должна просто работать.

3 голосов
/ 21 ноября 2011

Я написал пост в блоге давным-давно о том, чтобы заставить Джерси правильно сериализовать одноэлементные массивы, не уверен, устарел ли он сейчас (с середины 2010 года!), , но это может пригодиться.

Обратите внимание на комментарий Брила Паппина в блоге, демонстрирующий другой подход, который означает обновление используемой вами библиотеки Jettison.

Короче говоря, вы можете написать собственный JaxbContextResolver, который выглядит примерно так:

@Provider
@Component
public class JAXBContextResolver implements ContextResolver {

    private JAXBContext context;

    public JAXBContextResolver() throws Exception {
        MappedBuilder builder = JSONConfiguration.mapped();
        builder.arrays("invite");
        builder.rootUnwrapping(true);
        this.context = new JSONJAXBContext(builder.build(), Payload.class);
    }

    public JAXBContext getContext(Class objectType) {
        return (Payload.class.equals(objectType)) ? context : null;
    }
}

Для ясности, мой класс полезной нагрузки выглядел немного как

@XmlRootElement(name = "response")
@XmlAccessorType(XmlAccessType.FIELD)
public class Payload {

    @XmlElement(name = "invite")
    List invites;

    ... etc.

Относительно прекращения сериализации Джексоном свойств бина как нулевого, см. мой предыдущий ответ об использовании аннотаций для изменения этого поведения.

1 голос
/ 27 сентября 2012

Мне удалось устранить «ошибку» массива JSON в недавней библиотеке json в Джерси (v1.14 сентября 2012 г.).Секретный компонент - магия JSONConfiguration и ContextResolver.См. Мой следующий пост, в котором приведен пример полного кода, настроенный ContextResolver и остальная часть Класс приложения может быть несколько нечеткой логикой на первый взгляд.

Как сериализовать примитивы Java с использованием Jersey REST

Примитивы и нулевой или одноэлементный массив List правильно сериализованы в документ JSON.

0 голосов
/ 05 февраля 2014

Да, мы также столкнулись с той же проблемой. Джексон не может сериализовать список с 0 или одним элементом в массив json. Поэтому мы попытались использовать ObjectMapper Json для преобразования объекта POJO в String. Он будет сериализовать список Java в массив json независимо от количества элементов в списке (0 или 1 или> 0). Код будет выглядеть так:

 request = new ObjectMapper().writeValueAsString(pojo);

где запрос имеет тип Object. Это не повлияет на ответ. Вы можете попробовать.

...