2010-03-30 3 views
4

У меня проблема с пользовательской сериализацией Java. У меня есть график объектов и вы хотите настроить, где остановиться, когда я сериализую корневой объект от клиента к серверу.Сериализация части объекта графа

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

Компания
Сотрудника (аннотация)
Менеджер расширяет сотрудники
секретаря расширяет Сотрудник
Аналитик расширяет Сотрудник
Проект

Вот отношения:
компании (1) - - (n) Сотрудник
Менеджер (1) --- (n) Проект
Аналитик (1) --- (n) Проект

Представьте, я нахожусь на стороне клиента, и я хочу создать новую компанию, назначить ее 10 сотрудникам (новым или некоторым существующим) и отправить эту новую компанию на сервер. То, что я ожидаю в этом сценарии, - это сериализовать компанию и всех ограничивающих сотрудников на стороне сервера, потому что я сохраню отношения в базе данных. До сих пор не проблема, поскольку механизм сериализации Java по умолчанию сериализует весь граф объектов, исключая поле, которое является статическим или временным.

Моя цель - о следующем сценарии. Представьте, я загрузил компанию и ее 1000 сотрудников с сервера на клиентскую сторону. Теперь я хочу только переименовать название компании (или другое поле, прямо принадлежащее компании) и обновить эту запись. На этот раз я хочу отправить только объект компании на серверную сторону, а не весь список сотрудников (я просто обновляю имя, сотрудники в этом случае неактуальны). Моя цель также включает в себя конфигурацию высказывания, передачу компании И сотрудникам, а не Project-Relations, вы должны остановиться там.

Знаете ли вы какую-либо возможность достижения этого в общем виде без реализации writeObject, readObject для каждого объекта Entity-Object? Какие будут ваши предложения?

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

ответ

1

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

Способ пользовательской сериализации реализует Externalizable

+0

Привет Bozho, спасибо за быстрый ответ. Я также думаю, что решение DTO является хорошим. Это было сконструировано таким образом, чтобы сэкономить время на поддержание кода, дублирование для DTO и DO отдельно. Сейчас мы находимся в таком фазе, где проблема должна решаться без интеграции DTO. В противном случае потребуется много времени, так как у нас есть кеш на клиенте, который должен быть обновлен в соответствии с DTO на этот раз и т. Д. – Max

0

Я бы сказал, короткий ответ на ваш вопрос нет, такая разнообразная логика сериализации не может быть легко реализована без написания сериализации самостоятельно. Тем не менее, альтернативой может быть запись нескольких пар сериализатора/десериализатора (XML, JSON, независимо от вашего любимого формата, вместо стандартного ввода встроенной сериализации). а затем запускать ваши объекты через эти пары, отправляя какую-то метаинформационную преамбулу.

, например, следующие ваши сценарии выше вы можете иметь эти пары (де) сериализации механизмов

  1. (де) serializeCompany (Компания с) - для информации базовой компании
  2. (де) serializeEmployee (Employee е) - для информации сотрудника
  3. (де) serializeEmployee (Компания с) - базовая информация сотрудников в компании
  4. (де) serializeRelationships (Компания с) - для проекта отношений

Для XML каждый из них может создать DOM дерева, а затем поместить их в корневой узел, содержащий метаинформацию т.е.

<Company describesEmployees="true" describeRelationships="false"> 
[Elements from (de)serializeCompany] 
[Elements from (de)serializeEmployee(Company c)] 
</Company> 

Одним из потенциальных «Гоча» с такой подход делает, что вы делаете десериализации в правильном порядке в зависимости от вашей модели (т. е. убедитесь, что вы сначала десериализуете компанию, затем сотрудников, затем отношения). Но этот подход должен предоставить вам возможность писать только «фактическую» сериализацию один раз, а затем вы можете создавать свои различные транспортные модели на основе составов этих произведений.

0

Вы можете взять объект swizzling, где вы отправляете объект «заглушка» по проводу вашему клиенту.

Профессионалы

  • и тот же объект графа логически доступен на стороне клиента без накладных расходов на сериализации/десериализации ненужные данные.
  • Реализации полного/заглушки можно поменять местами при необходимости без изменения кода клиента.

Против

  • Накладные в призыве добытчиков, которые приводят к динамической загрузке дополнительных атрибутов с помощью вызова к серверу скрыт от клиента, который может быть проблематичным, если вы не контролируете клиент код; например Невольно пользователь может совершать дорогостоящий вызов много раз в жесткой петле.
  • Если вы решили кэшировать данные локально на стороне клиента, вам необходимо обеспечить его синхронизацию с сервером.

Пример

/** 
* Lightweight company stub that only serializes the company name. 
* The collection of employees is fetched on-demand and cached locally. 
* The service responsible for returning employees must be "installed" 
* client-side when the object is first deserialized. 
*/ 
public class CompanyStub implements Company, Serializable { 
    private final String name; 
    private transient Set<Employee> employees; 
    private Service service; 

    public Service getService() { 
    return service; 
    } 

    public void setService(Service service) { 
    this.service = service; 
    } 

    public String getName() { 
    return name; 
    } 

    public Set<? extends Employee> getEmployees() { 
    if (employees == null) { 
     // Employees not loaded so load them now. 
     this.employees = server.getEmployeesForCompany(name); 
    } 

    return employees; 
    } 
} 
Смежные вопросы