Spring Boot – Widoki

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

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);
}
}
view raw Main.java hosted with ❤ by GitHub

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.

Widok strony błędu

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>
view raw JTwig.xml hosted with ❤ by GitHub

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");
}
}
view raw MainController.java hosted with ❤ by GitHub

Stwórzmy teraz widok. W katalogu src/main/resources/views/ dodajemy plik index.twig, klasycznie o treści:

<h1>Hello World from view!</h1>
view raw view.html hosted with ❤ by GitHub

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})
view raw ComponentScan.java hosted with ❤ by GitHub

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>
view raw view2.twig hosted with ❤ by GitHub

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>
view raw view3.twig hosted with ❤ by GitHub

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>
view raw view4.twig hosted with ❤ by GitHub

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ą.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *