2014-02-05 3 views
13

Я пытаюсь найти наилучшее решение проблемы, с которой я сталкиваюсь, с отображением простой структуры bean-структуры, которая отправляется в приложение на основе браузера. Нынешнее требование состоит в том, чтобы управлять большинством элементов управления отображением на старой базе данных Java. В настоящее время мы имеем слой стиля обслуживания, который производит объекты значений, без логики отображения встроенной в них нравятся:Комплексное отображение бина

public class Example1 { 
    String value1; 
    Boolean value2; 
    Example3 value3; 

    public String getValue1(){...} 
    public void setValue1(){...} 
    .... 
} 

Моя цель состоит в том, чтобы иметь возможность сопоставить общую структуру по всем полям, таких, что он добавляет новую структуру дисплея что требуется интерфейсом. Я хотел бы управлять только структурой исходного класса структуры (Example1) и просто устанавливать дополнительные значения в оболочке на старый сервисный уровень.

Родовая структура будет иметь форму следующего класса:

public class Presentable<T> { 
    T value; 
    boolean visible = true; 
    boolean mandatory = false; 
    List<String> errors = new ArrayList<>(); 

    public T getValue() {...} 
    public void setValue(T value) {...} 
    ... 
} 

Конечный результат будет выглядеть примерно следующий, где значение равно значение в исходной структуре:

public class Example2{ 
    Presentable<String> value1; 
    Presentable<Boolean> value2; 
    Presentable<Example3> value3; 

    public Presentable<String> getValue1(){...} 
    public void setValue1(){...} 
    ... 
} 

Есть ли решение этой проблемы без написания класса стиля Example2 и копирования в каждом отдельном значении? Я открыт для изменения класса Example1, поскольку он не влияет на потребителей старой службы.

Спасибо.

+0

Обновление: Единственное решение, которое я нашел, это использование генерации кода с аннотациями. Хотя я написал быстрый рабочий стол, это очень грязно. –

+0

вам нужно иметь несколько объектов из примера 1 на основе требований клиента. Итак, для чего вам нужен общий класс. Вы можете использовать сопоставление arraylist переднего конца, поэтому каждый раз, когда пользователь добавляет новый, он просто автоматически добавляет еще один объект Example1 в ArrayList, у вас будет список , который содержит в нем все объекты example1. – Dileep

ответ

4

Вы можете использовать в основном AOP (Aspect Oriented Programming) с пружиной. Весной вы можете создать прокси-объект с дополнительной информацией, которая вам нужна. Хорошая отправная точка: http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/

Официальная страница на Aspect Oriented Programming: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html

Этот пример/ответ может быть полезным: Intercepting method with Spring AOP using only annotations

+0

Это близко к тому, что я ищу, но Spring - это не вариант, хотя я понимаю, что большинство приложений Enterprise Java сегодня включают Spring. –

1

Так что я не уверен, если я правильно понял вы. Однако ...

Это место, где мы можем очень легко использовать отражение.

Для нашего класса Example1.class мы вызываем getDeclaredMethods, getDeclaredFields (в ​​простом случае) или getMethods, getFields в более сложных (простое pojo, но с наследованием). Возможно, вам понадобится простая логика, например, чтобы удалить поля с помощью модификатора static или что-то в этом роде.

Для каждого метода/полей мы получаем соответствующий метод/поле из Example2.class с getMethod (имя String) или ПолучитьПолеЗаголовком (имя String)

и установить нашу ценность для нового объекта в поле или сеттер. Если есть проблема с такими модификаторами, как private, мы используем setAccessible.

Некоторый код для простого случая использования:

public Example2 decorateWithWrapper(Example1 obj) { 
    Example2 wrapped = new Example2(); 
    for (Field field : obj.getClass().getDeclaredFields()) { 
     Field toAssign = wrapped.getClass().getField(field.getName()); 
     toAssign.setAccessible(true); 
     toAssign.set(wrapped, field.get(obj)); 
    } 
    return wrapped; 
} 

Это довольно легко сделать более универсальный метод от этого выше, если это необходимо.

Вам не нужна внешняя библиотека или инструмент.

1

Вы можете использовать Джексон ObjectMapper и настроить [Dozer][1] картографа сделать это комплексное отображение боба и пусть JSON связи между прикладной & браузером.

Dozer позволяет вам сопоставить класс в другом поле по полю. Базовый код Dozer отображения показан ниже:

<mappings>   
    <mapping> 
    <class-a>org.dozer.vo.TestObject</class-a> 
    <class-b>org.dozer.vo.TestObjectPrime</class-b> 
    <!-- Any custom field mapping xml would go here --> 
    </mapping> 
</mappings> 

Здесь, в приведенном выше примере, все переменные TestObject в настоящее время отображается на TestObjectPrime. В вашем случае, вам нужно добавить пользовательское сопоставление в этой конфигурации, так как выставлены ниже:

<mapping> 
    <class-a>org.dozer.vo.deep.SrcDeepObj</class-a> 
    <class-b>org.dozer.vo.deep.DestDeepObj</class-b> 

    <field> 
    <a>srcNestedObj.src1</a> 
    <b>dest1</b> 
    </field> 

    <field> 
    <a>srcNestedObj.src2</a> 
    <b>dest2</b> 
    </field> 

    <field> 
    <a>srcNestedObj.srcNestedObj2.src5</a> 
    <b>dest5</b> 
    </field> 

    <field><!-- java.util.List to java.util.List --> 
    <a>srcNestedObj.hintList</a> 
    <b>hintList</b> 
    <a-hint>java.lang.String</a-hint>   
    <b-hint>java.lang.Integer</b-hint> 
    </field> 

    <field> 
    <a>srcNestedObj.hintList2</a> 
    <b>hintList2</b> 
    <a-hint>org.dozer.vo.TheFirstSubClass</a-hint> 
    <b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint> 
    </field> 

    <field copy-by-reference="true"> 
    <a>srcNestedObj.hintList3</a> 
    <b>hintList3</b> 
    </field-deep> 

</mapping> 

Как бульдозер учебник говорит:

можно отобразить глубокие свойства. Например, если у есть объект со свойством String. Ваш другой объект имеет свойство String , но он находится на нескольких уровнях в пределах графа объектов. В примере ниже DestDeepObj имеет вложенные атрибуты в пределах объекта график, который необходимо сопоставить. Подсказки типов поддерживаются для глубокого поля сопоставлений. Также могут использоваться атрибуты copy-by-reference, type = one-way и .

Выше приведены примеры из дозатора documentation.

Шишир

0

Чтобы включить AspectJ, вам нужно aspectjrt.jar, aspectjweaver.jar и весна-aop.jar. Для нашего класса Example1.class мы вызываем getDeclaredMethods, getDeclaredFields (в ​​простом случае) или getMethods, getFields в более сложных (простое pojo, но с наследованием).

Смежные вопросы