W poprzednich postach pisałem jak zacząć przygodę ze Spring Bootem oraz jak się połączyć z bazą danych. Dotychczas dane do przeglądarki zwracane były jako stringi. Jak już pewnie się domyślasz, istnieją lepsze sposoby, aby ładnie zaprezentować nasze dane, a do tego oddzielić logikę aplikacji od prezentacji.
Spring wspiera różne technologie widoków. Od tradycyjnych JSP (http://pl.wikipedia.org/wiki/JavaServer_Pages), do Themyleaf (http://www.thymeleaf.org/), Twig (http://twig.sensiolabs.org/, implementacja dla Javy JTWIG: http://jtwig.org/), FreeMarker, Groovy czy Velocity.
Widoki JSP mają kilka znanych ograniczeń, przez co powinny być unikane. Osobiście lubię widoki TWIG dlatego skupie się na nich, inne silniki szablonów implementuje się w analogiczny sposób.
Kod źródłowy gotowego projektu można znaleźć pod adresem: https://github.com/mloza/spring-boot-views
Wpis jest częścią serii wpisów na temat Spring Boot. Zapraszam do zapoznania się z pozostałymi wpisami na blogu!
- Spring Boot – szybkie tworzenie aplikacji web w Javie
- Spring Boot – Interakcja z bazą danych czyli Spring Data JPA
- Spring Boot – Widoki
- Użycie Spring Security w Spring Boot
- Spring Boot Web – Przekazywanie zmiennych do aplikacji przez URL czyli użycie @RequestParam i @PathVariable
- Spring Boot Test – testowanie aplikacji w Spring Boocie
- Wsparcie dla pola typu JSONB w PostgreSQL dla Spring Data JPA + Hibernate
- Wysyłanie plików na serwer przez Spring Boot
- Spring Boot – Spring Data JPA część II: Powiązania między tabelami
- Spring Mail + Spring Boot – łatwe wysyłanie maili z aplikacji w Javie
- Docker + Spring Boot – zamykamy aplikację w kontenerze Dockerowym
- Java Bean Validation + Spring Boot – sprawdzanie poprawności danych w Spring Boocie
- Spring Boot + Swagger UI
- Serwer Amazon EC2 i SSL od Let’s encrypt w aplikacji Spring Boot
Konfiguracja początkowa
Możesz użyć projektu z poprzedniego postu: http://blog.mloza.pl/spring-boot-szybkie-tworzenie-aplikacji-web-w-javie/. Robiąc to, możesz pominąć ten rozdział.
Zacznijmy od stworzenia nowego projektu Maven i dodaniu następujących elementów w pom.xml:
Kolejnym krokiem jest stworzenie klasy, która będzie odpalała nam projekt. Powinna wyglądać następująco:
@EnableAutoConfiguration | |
@ComponentScan | |
public class Main { | |
public static void main(String[] args) { | |
SpringApplication.run(Main.class); | |
} | |
} |
W tym momencie możemy uruchomić aplikację. Gdy całość się uruchomi, wchodzimy przeglądarką pod adres: http://localhost:8080/. Naszym oczom powinna się ukazać strona błędu, taka jak poniżej. Znaczy, że projekt działa, a strona błędu pokazuje się, ponieważ jeszcze nic nie ma w naszej aplikacji.

Konfiguracja JTWIG
Pierwszym krokiem jest dodanie kolejnej zależności do pom.xml:
<dependency> | |
<groupId>com.lyncode</groupId> | |
<artifactId>jtwig-spring</artifactId> | |
<version>2.1.7</version> | |
</dependency> |
Następnie musimy powiedzieć Springowi, gdzie ma szukać naszych widoków. Robimy to poprzez utworzenie klasy z adnotacją @Configuration. Klasa ta dostarczy Bean, który zostanie użyty do rozwiązywania widoków:
@Configuration | |
public class WebAppConfiguration { | |
@Bean | |
public ViewResolver viewResolver() { | |
JtwigViewResolver jtwigViewResolver = new JtwigViewResolver(); | |
jtwigViewResolver.setPrefix("classpath:views/"); | |
jtwigViewResolver.setSuffix(".twig"); | |
return jtwigViewResolver; | |
} | |
} |
Teraz potrzebujemy kontroler, który obsłuży wywołanie, zacznijmy od najprostszej wersji:
@Controller | |
public class MainController { | |
@RequestMapping("/") | |
public ModelAndView index() { | |
return new ModelAndView("index"); | |
} | |
} |
Stwórzmy teraz widok. W katalogu src/main/resources/views/ dodajemy plik index.twig, klasycznie o treści:
<h1>Hello World from view!</h1> |
I to już prawie wszystko, ostatnim krokiem jest poinformowanie Springa, że powinien szukać naszych klas i rozwiązywać konfigurację. Jeśli wszystkie klasy zostały umieszczone w jednym pakiecie, to powinien je wykryć automatycznie. Jeśli nie, to adnotację @ComponentScan w klasie Main należy zmodyfikować do postaci:
@ComponentScan(basePackageClasses = {MainController.class, WebAppConfiguration.class}) |
Po restarcie aplikacji i odświeżeniu strony powinniśmy otrzymać nasz widok.
Przekazywanie zmiennych do widoku
Użycie widoków pozwala na odseparowanie logiki aplikacji od sposobu prezentacji danych. Jednak dane te musimy jakoś przekazać z kontrolera do widoku. Najczęściej dane będą pochodzić z bazy danych, jednak dla uproszczenia dane zostaną stworzone w kontrolerze. Zmodyfikujmy kontroler do postaci:
Zwracana wartość została przypisana do zmiennej, aby można było jej użyć przed zwróceniem z kontrolera. Następnie wywołujemy na niej metodę addObject(nazwa, wartość). Dzięki temu wartość przekazana do metody będzie widoczna w widoku pod wybraną nazwą. Możemy tutaj przekazywać zarówno prymitywy (int, long, double) jak i obiekty, tablice, listy. W tym przykładzie przekazujemy String i tablicę Stringów. Zacznijmy od wyświetlenia zmiennej greetings. W Twigu do zmiennych odwołujemy się poprzez {{ zmienna }}. Zmodyfikujmy widok do postaci:
<h3>{{ greetings }}</h3> |
Restartujemy aplikacje i odświeżamy przeglądarkę. Powinniśmy ujrzeć napis: Hello world from variable!
TIP: jeśli używasz IntelliJ, możesz uruchomić aplikację w trybie debugowania, wtedy wywołanie Make Project (Ctrl+F9) wystarczy aby zaktualizować widok. W ten sposób również można aktualizować klasy jeśli dokonujemy tylko zmian zawartości metod, zmiana interfejsu lub adnotacji wymaga pełnego restartu. Ten sam sposób powinien zadziałać w Eclipse jednak nie sprawdzałem tego.
Iterowanie po zmiennych
Wiemy już jak wyświetlić zmienną. Co jeśli chcemy wyświetlić zawartość tablicy? Dodajmy do widoku następujący kod:
<ul> | |
{% for i in greetingsArray %} | |
<li>{{ i }}</li> | |
{% endfor %} | |
</ul> |
Kod ten to nic innego jak pętla for na sterydach. Udostępnia ona też zmienną loop, która posiada kilka ciekawych elementów jak np. aktualny index. Używając go, możemy dodać numerację elementów:
<ul> | |
{% for i in greetingsArray %} | |
<li>{{ loop.index+1}}. {{ i }}</li> | |
{% endfor %} | |
</ul> |
W wyniku powinniśmy otrzymać coś podobnego:

Podsumowanie
Umiemy już pracować z widokami. Opis składni szablonów TWIGa można znaleźć na stronie TWIGa oraz JTWIG. Aby użyć innego silnika szablonów, wystarczy go dodać jako zależność do Mavena i zmienić ViewResolver. W kolejnym poście dodam więcej informacji o pracy z samymi szablonami Twiga i możliwościami, jakie one dają.