Spring MVC, REST, Джексон, Dojo dojox.data.jsonRestStore, как сделать ссылки в стиле dojo? - PullRequest
0 голосов
/ 15 декабря 2011

Довольно простой вопрос, трудно найти ответ:

Я хочу сериализовать в JSON мои сущности POJO JPA со ссылками, подобными Dojo, чтобы использовать его с dojox.data.JsonRestStore.

Серверная часть сделана с использованием Spring MVC и HttpConverters, чтобы сделать его веб-приложением RESTfull. Я использую JacksonJson для преобразования сущностей JPA в JSON.

Как и у многих людей, у меня есть проблемы с несколькими ссылками. @JsonBackReference и @JsonManagedReference не справляются с задачей!

Рассматривая этот базовый пример:

public class A {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable=false)
    private String field;

    @OneToMany(mappedBy = "b")
    private List<B> bs;
}

public class B {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    private A a;
}

С помощью базового конвертера Джексона Джсона вы получаете что-то вроде этого (учитывая, что вы поместили @JsonBackReference и @JsonManagedReference):

{ id:1, fieldB:"bbbbb", a: { id:1, fieldA: "aaaaaa" }}

В конкретном приложении иметь список bs для объектов A в большинстве случаев бессмысленно. Но важно знать, что за объект A находится в поле B.a (по крайней мере, для меня).

Теперь, проблема заключается в том, что ссылки копируются, и вы можете получить какой-то серьезный большой JSON без большого количества данных.

Dojo Framework предоставляет эталонный стандарт, объясненный здесь: http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/ и http://dojotoolkit.org/reference-guide/dojox/data/JsonRestStore.html.

Так что я ищу способ определить это следующим образом:

{ id:1, fieldB:"bbbbb", a: { $ref: "getA/1"}}

Первая проблема: Джексон, очевидно, не может знать, какой URL вы будете использовать для ссылки.

Чтобы решить эту проблему, я сделал очень простой интерфейс, подобный этому:

public interface EntityWithId {
    public Long getId();
    public void setId(Long id);
}

Этот интерфейс был реализован всеми моими сущностями, и я сделал этот очень простой JsonSerializer:

public class EntityIdSerializer extends JsonSerializer<EntityWithId> {

    @Override
    public void serialize(EntityWithId value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
                jgen.writeStartObject();
                jgen.writeStringField("$ref", "db/" + value.getClass().getSimpleName() + "/" + value.getId().toString());
                jgen.writeEndObject();
    }
}

С этими двумя я получил желаемый JSON, добавив @ JsonSerialize (используя = EntityIdSerializer.class) к полям @ ManyToOne .

Нет ли более стандартного подхода? Dojo dojox.data.JsonRestStore звучит очень многообещающе, поскольку вы можете комбинировать его с большим количеством виджетов Dijits, но действительно ли это хорошая вещь, которую можно попробовать и попробовать? Разве мое приложение REST не будет сильно ограничивать Dojo?

Спасибо за ваши ответы!

1 Ответ

0 голосов
/ 16 декабря 2011

Подход Dojo звучит так, как будто он требует работы с полным логическим деревом, чтобы иметь возможность использовать ссылки на основе местоположения. Это не будет хорошо работать с Джексоном, который поддерживает полностью инкрементное связывание данных, то есть только подмножество логического существа, доступного в точке, где данные считываются или записываются.

Так что Джексон не поддерживает его по умолчанию; и этот подход не считается в значительной степени стандартным (AFAIK). По крайней мере, я не видел, чтобы это поддерживалось библиотеками Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...