Wyślij zapytanie Dołącz do Sii

W tym artykule przedstawię w sposób ogólny technologię Vaadin – framework w języku Java, a następnie omówię kilka różnic występujących między wersją 7 a 8 tego frameworka. Dodatkowo wyjaśnię w jaki sposób można przeprowadzić migrację między tymi wersjami zgodnie z zaleceniami twórców Vaadina. Zapraszam do przeczytania.

Wstęp – technologia Vaadin

Vaadin jest frameworkiem umożliwiającym tworzenie aplikacji webowych w języku Java. Jego podstawową zaletą jest to, że nie wymaga on dużej znajomości technologii frontendowych (co najwyżej podstawy) od programisty. Jeśli jednak programista potrzebuje użyć tych technologii w pisanej aplikacji w niestandardowy sposób, Vaadin daje taką możliwość i pozwala używać styli CSS, JavaScript, HTML5 itp.  Sposób tworzenia interfejsu użytkownika w frameworku Vaadin przypomina tworzenie aplikacji desktopowej w Swingu. Programista tworzy UI z komponentów dostarczonych przez Vaadina (np. TextField, ComboBox) i następnie może zarządzać ich ułożeniem stosując odpowiednie layouty. Aplikację w stylu „Hello World” możemy utworzyć w bardzo prosty sposób np. pobierając plugin do Eclipse (Vaddin plugin for Eclipse), a następnie utworzyć projekt za pomocą archetypu mavena (file -> new -> other -> Vaadin Project). Utworzona w ten sposób aplikacja w Vaadinie 7 składa się z elementów przedstawionych na rysunku 1.1

rys1.1 - Vaadin - różnice między wersją 7 a 8
Rys. 1.1 Podstawowy projekt w Vaadinie

Jak widać na rysunku 1.1 struktura nie jest bardzo złożona, istnieje tylko jedna klasa oraz kilka plików .css, .scss i .ico odpowiadających za style wyglądu aplikacji. Istotną rzeczą jest jednak klasa MyUI, której zawartość prezentuje Listing 1.2:

@Theme("mytheme")
public class MyUI extends UI {
 
private static final long serialVersionUID = 2123628334309501295L;
 
@Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout(); // stworzenie layoutu pionowego
// (komponenty będą ułożone jeden pod drugim)
 
final TextField name = new TextField(); // stworzenie pola textowego
name.setCaption("Type your name here:"); // dodanie podpisu do pola textowego
Button button = new Button("Click Me"); // Stworzenie przycisku
 
layout.addComponents(name, button); // dodanie pola textowego i przycisku do layoutu
layout.setMargin(true); // margines dla layoutu
layout.setSpacing(true); // margines między komponentami w layoucie
 
setContent(layout); // ustawienie layoutu jako zawartości widoku strony
}
 
@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

Listing 1.2 Klasa MyUI

Klasa MyUI rozszerza klasę UI odpowiadającą treści wyświetlanej w przeglądarce. W metodzie init można tworzyć konkretny widok z komponentów – tak też zrobiono na Listingu 1.2.  Warto zwrócić uwagę także na wewnętrzna klasę statyczną MyUIServlet, dzięki której została dokonana niezbędna konfiguracja:

  • @WebServlet wskazuje na jakie żądanie ma być zmapowany servlet, jego nazwę, oraz czy servlet ma wspierać operacje asynchroniczne.
  • @VaadinServletConfiguration wskazuje na jaki widok ma być przekierowany użytkownik oraz w jakim trybie ma pracować (produkcyjnym lub nie).

Efekt działania utworzonej aplikacji został przedstawiony na rysunku 1.3.

rys 1.3 300x219 - Vaadin - różnice między wersją 7 a 8
Rys 1.3 Uruchomiona aplikacja w przeglądarce

Jak na aplikację składającą się z jednej klasy i paru linijek kodu, efekt wydaje się całkiem niezły prawda? ? Mam nadzieję, że przybliżyłem Ci trochę technologię Vaadin, w następnej sekcji opiszę kilka różnic między Vaadinem 7 a Vaadinem 8.

Vaadin 7 i Vaadin 8 – różnice

Vaadin 7 przestał być wspierany w lutym 2019 roku, dlatego powstała potrzeba przepisania istniejących aplikacji napisanych w Vaadinie 7 na Vaadina 8, co wiąże się z poznaniem nowości i usprawnień nowszej wersji tej technologii.

Nowa wersja frameworka idzie w parze wraz z większymi wymaganiami powiązanych technologii. Aby móc pracować z Vaadinem 8, należy korzystać z javy minimum wersji 8 oraz servlet minimum w wersji 3.0. W Vaadinie 8 nastąpiło kilka kluczowych zmian dodających nowe funkcje oraz naprawiające niedoskonałości istniejące w Vaadinie 7. Przedstawię pokrótce kilka problemów występujących w Vaadinie 7, które zostały rozwiązane w Vaadinie 8.

Zmiany w komponencie Grid

Grid jest komponentem odwzorowującym tabelę, Rys. 2.1 przedstawia jego wygląd w aplikacji.

rys. 2.1 - Vaadin - różnice między wersją 7 a 8
Rys. 2.1. Przykładowy Grid

W Vaadinie 7 komponent ten miał kilka braków, które zostały poprawione w Vaadinie 8:

  •  Brak możliwości dodawania komponentów do komórek grida

W Vaadinie 7 aby tego dokonać trzeba było ingerować w kod front-endowy lub tworzyć specjalne implementacje komponentów w Javie, co znacznie utrudniało wykorzystanie tej funkcji grida. W Vaadinie 8 jest to równie proste co ustawianie zwykłego tekstu.

  • Brak możliwości przeciągania wierszy grida do innego grida.

W Vaadinie 7 nie było takiej możliwości, nie jest to funkcjonalność niezbędna, jednak jest to coś nowego, co można wykorzystać w tworzonym systemie.

  • Brak możliwości tworzenia struktury drzewiastej w gridzie.

W Vaadinie 8 dodano komponenty Tree i TreeGrid, które dają taką możliwość.

Zmiany w api, upraszczające kod

  • Uproszczenie sposobu wyświetlania obiektów javy w komponentach:

Na przykładzie grida – w Vaadinie 7 wymagane było najpierw utworzenie kontenera, który należało wypełnić obiektami a następnie przekazać go do Grida. W Vaadinie 8 obiekty można przekazać bezpośrednio do Grida. Listing 2.2. oraz Listing 2.3. przedstawiają te różnice.

Grid grid = new Grid();
List<MyObject> objects = new ArrayList<>();
BeanItemContainer<MyObject> container = new BeanItemContainer<>(MyObject.class,objects);
grid.setContainerDataSource(container);

Listing 2.2. Dodanie obiektów do Grida w Vaadinie 7

Grid<MyObject> grid = new Grid<>();
List<MyObject> objects = new ArrayList<>();
grid.setItems(objects);

Listing 2.3. Dodanie obiektów do Grida w Vaadinie 8

  • Uproszczenie sposobu pobierania wartości z komponentów podczas ich zmiany wartości

W Vaadinie 7 dodając listener wywoływany podczas zmiany wartości np. comoboxa, procedura pobrania nowo ustawionej wartości była nieco wydłużona, należało posłużyć się interfejsem Property, w Vaadinie 8 wartość tą można pobrać bezpośrednio z eventu. Wynika to ze zmiany modelu danych w Vaadinie 8.

ComboBox combobox = new ComboBox();
combobox.addValueChangeListener(event -> {
Property<String> property = event.getProperty();
String value = property.getValue();
System.out.println("Value : " + value);
});

Listing 2.4. Pobranie zmienianej wartości comboboxa w Vaadinie 7

ComboBox<String> combobox = new ComboBox<>();
combobox.addValueChangeListener(event -> {
String value = event.getValue();
System.out.println("Value : " + value);
});

Listing 2.5. Pobranie zmienianej wartości comboboxa w Vaadinie 8

  • Uproszenie Lazy loadingu

W Vaadinie 7 w celu otrzymania efektu lazy loading np. w Gridzie, należało utworzyć własną implementację kontenera obsługującego ten przypadek. W Vaadinie 8 zostało to maksymalnie uproszczone. Wystarczy użyć metody Grida setDataProvider() przedstawionej poniżej:

public void setDataProvider(FetchItemsCallback<T> fetchItems, SerializableSupplier<Integer> sizeCallback)

Listing 2.6 Metoda setDataProvider

Interfejs FetchItemsCallback posiada jedną metodę przyjmującą 3 parametry:

  • List<QuerySortOrder> – listę określającą sposób sortowania
  • Int offset – index początkowy obiektów do pobrania
  • Int limit – liczba obiektów do pobrania

Interfejs SerializableSupplier ma za zadanie zwrócić liczbę wszystkich docelowych elementów do wyświetlenia. Poniżej została przykładowa implementacja serwisu, spełniającego oba warunki implementacji interfejsów FetchItemsCallback (metoda findAll()) i SerializableSupplier (metoda count()).

public class MyService {
 
List<MyObject> data = new ArrayList<>();
 
public MyService() {
 
fillData();
}
 
private void fillData() {
 
for (int i = 0; i < 100; i++) {
data.add(new MyObject(i));
}
}
 
public Stream<MyObject> findAll(List sortOrder, int offset, int limit) {
 
List<MyObject> result = IntStream.range(offset, offset + limit).mapToObj(i -> data.get(i))
.collect(Collectors.toList());
return result.stream();
}
 
public int count() {
 
return data.size();
}
 
}

Listing 2.7. Klasa MyService

Obiekt MyObject – do wyświetlenia w gridzie:

public class MyObject {
 
private int value;
 
public MyObject(int value) {
 
this.value = value;
}
 
public int getValue() {
 
return value;
}
 
public void setValue(int value) {
 
this.value = value;
}
}

Listing 2.8. Klasa MyObject

MyService service = new MyService();
Grid<MyObject> grid = new Grid<>(MyObject.class);
grid.setDataProvider(service::findAll, service::count);

Listing 2.9. Zastosowanie lazy loading w Gridzie

Oprócz powyższych korzyści, dodatkowym atutem w Vaadinie 8 jest znacznie lepszy performance. Na przykład wyświetlając 100 000 obiektów w gridzie czas generowania takiego grida w starej wersji Vaadina trwał około 233ms a w przypadku Vaadina 8 tylko 9ms, różnica zatem jest bardzo duża. Vaadin 8 posiada także lepszą optymalizację strony klienckiej np. poprzez zastosowanie technologii flexbox, wiąże się to jednak z wsparciem przez nowsze wersje przeglądarek (Firefox minimum wersja 28, Chrome minimum 21), IE tylko częściowo wspiera tą technologię, dlatego nie jest zalecany.

Migracja Vaadina 7 do Vaadina 8

Twórcy Vaadina 8 dostrzegli problem w rozbieżności między Vaadinem 7 a Vaadinem 8, dlatego przygotowali specjalne compatilibity packages, zawierające elementy starego API. W projekcie maven użycie compability packages jest bardzo proste, wystarczy podmienić odpowiednie zależności w pliku pom.xml. Na listingu 3.1 znajduje się zależność wykorzystywana w Vaadinie 7, na listingu 3.2. znajduje się zależność wykorzystywana w Vaadinie 8 przy migracji:

<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-server</artifactId>
<version>7.7.6</version>
</dependency>

Listing 3.1. Zależność o artefakcie vaadin-server w Vaadinie 7

<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-compatibility-server</artifactId>
<version>8.0.0</version>
</dependency>

Listing 3.2. Zależność o artefakcie vaadin-compatibility-server w Vaadinie 8

Dzięki temu zabiegowi, wszystkie klasy użyte w ramach artefaktu vaadin-server w vaadinie 7, będą mogły zostać użyte po migracji do Vaadina 8. Poniżej spis wszystkich compatibility artefaktów dostępnych w Vaadinie 8:

  • vaadin-compatibility-server
  • vaadin-compatibility-client
  • vaadin-compatibility-client-compiled
  • vaadin-compatibility-shared
  • vaadin-compatibility-themes

Po podmianie zależności należy pamiętać o zaktualizowaniu importów i widgetsetów, aby nie robić tego ręcznie powstał migration tool – Vaadin Maven plugin może wykonać tą pracę przy użyciu targetu vaadin:upgrade8. Po wykonaniu tej operacji migracja powinna zakończyć się sukcesem. Warto podkreślić, że powyższa migracja pozwala nam użyć Vaadina 7 w Vaadinie 8. Chcąc używać komponentów Vaadina 8 należy przepisać stare komponenty na nowe, niestety jest to nieuniknione gdyż Vaadin 8 stosuje zupełnie inny model danych od Vaadina 7.

4.4/5 ( głosy: 8)
Ocena:
4.4/5 ( głosy: 8)
Autor
Avatar
Krzysztof Krocz

Java Developer w Sii Polska od 2017 roku. Na co dzień pracuję m.in. w technologiach Vaadin, Hibernate, EJB, Docker.

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Może Cię również zainteresować

Pokaż więcej artykułów

Bądź na bieżąco

Zasubskrybuj naszego bloga i otrzymuj informacje o najnowszych wpisach.

Otrzymaj ofertę

Jeśli chcesz dowiedzieć się więcej na temat oferty Sii, skontaktuj się z nami.

Wyślij zapytanie Wyślij zapytanie

Natalia Competency Center Director

Get an offer

Dołącz do Sii

Znajdź idealną pracę – zapoznaj się z naszą ofertą rekrutacyjną i aplikuj.

Aplikuj Aplikuj

Paweł Process Owner

Join Sii

ZATWIERDŹ

This content is available only in one language version.
You will be redirected to home page.

Are you sure you want to leave this page?