Dopiero teraz, przy piątym wpisie w ramach konkursu Daj się poznać, osiągnęłam etap aplikacji “Witaj Świecie”. No cóż. W tym artykule opowiem krótko co przy tej okazji zrobiłam i co mnie zaskoczyło. Kod jest, oczywiście, dostępny w GitHubie.
Spis treści
Szkielet aplikacji
Za radą Java Magazine, szkielet aplikacji wygenerowałam przy użyciu serwisu Spring Initializr.

Najważniejsze elementy w strukturze aplikacji to (tradycyjnie zresztą):
- katalog src/main/java z kodem w języku Java (domyślnie wypełniany przez Spring Initializr jedną klasą o nazwie
Application
), - katalog src/test/java z testami jednostkowymi,
- src/main/resources to miejsce na zasoby; podkatalog static ma zawierać pliki przetwarzane po stronie klienta (obrazki, javascript), a podkatalog templates szablony przetwarzane po stronie serwera,
- plik pom.xml to informacje dla Mavena, którego wybrałam jako narzędzie do budowania mojego projektu; zawiera przede wszystkim listę potrzebnych mi bibliotek.
Hello World!
Aplikacja kompilowała się już w poprzedniej odsłonie, ale teraz zależało mi na jej uruchomieniu i wyświetleniu czegoś w przeglądarce. W oparciu o tutorial na stronie Springa powstał ten oto skomplikowany kontroler:
1 2 3 4 5 6 7 8 9 |
@RestController public class HelloController { @RequestMapping("/") public String index() { return "Szafbook: work in progress!"; } } |
@RestController
to adnotacja, która sprawi, że klasa będzie mogła obsługiwać żądania REST. Jej użycie jest równoważne zastosowaniu dwóch innych adnotacji:@Controller
and@ResponseBody
. W ten sposób tworzę kontroler, który zwraca dane tekstowe (a nie kod HTML).@RequestMapping
pozwala określić adres, pod jakim ma być dostępny kontroler. W naszym wypadku będzie to adres najwyższego rzędu.
Klasa uruchamiająca aplikację wygląda w najprostszej wersji tak:
1 2 3 4 5 6 7 8 9 |
@SpringBootApplication public class SzafbookApplication { public static void main(String[] args) { SpringApplication.run(SzafbookApplication.class, args); } } |
- Adnotacja
@SpringBootApplication
również grupuje kilka innych adnotacji. Być może najistotniejsza z nich to@ComponentScan
. Dzięki niej pakiet, w którym umieściłam kod zostanie przeszukany pod kątem usług sieciowych – w ten sposób znaleziony zostanieHelloController
.
Za radą tutoriala urozmaiciłam sobie efekt w konsoli dodając kod przeglądający ziarna (beans) dostępne w tzw. kontekście aplikacji.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@SpringBootApplication public class SzafbookApplication { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(SzafbookApplication.class, args); System.out.println("Inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } } } |
Jak to wygląda w przeglądarce? Zerknij na nagłówek tego wpisu.
Poniżej przedstawiam dane wypisane w konsoli. Zwróć uwagę, że aplikacja webowa jest uruchamiania w wierszu poleceń z pliku JAR, a nie z pliku WAR wgranego na serwer. Jak to możliwe? Otóż przy aktualnej konfiguracji, wynikowy plik JAR zawiera wbudowaną wersję serwera Tomcat. Wielkość szafbook-0.0.1-SNAPSHOT.jar to 33 MB…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
java -jar szafbook-0.0.1-SNAPSHOT.jar (...) Inspect the beans provided by Spring Boot: _halObjectMapper _linkDiscovererRegistry _relProvider actuatorMetricReader alpsController alpsConverter alpsJsonHttpMessageConverter annotatedEventHandlerInvoker annotationRelProvider applicationContextIdFilter auditEventRepository auditListener auditableBeanWrapperFactory autoConfigurationReportEndpoint backendIdConverterRegistry backendIdHandlerMethodArgumentResolver baseUri basicErrorController beanNameHandlerMapping beanNameViewResolver (...) |
Głupie wtopy: co zrobiłam nie tak przy pierwszym podejściu
Problem 1: Aplikacja buduje się (przy użyciu Mavena) w Eclipse i nie buduje się na zewnątrz. Rozwiązanie: Instalacja w systemie Mavena 3 i przestawienie Eclipse na tę samą instalację (wcześniej Eclipse korzystał z instalacji wbudowanej, a w systemie miałam Mavena 2).
Problem 2: java.lang.UnsupportedClassVersionError
Rozwiązanie: Zmiana wartości zmiennej JAVA_HOME
w systemie na wersję Javy używaną przez projekt w Eclipse.
Problem 3: Aplikacja działa w przeglądarce, ale w konsoli mam “java.lang.IllegalStateException: Tomcat connector in failed state
“. Rozwiązanie: Usunąć zduplikowane wywołanie SpringApplication.run
🙂 Sukcesem może zakończyć się tylko jedno z nich, potem port będzie już zajęty.
Co dalej?
Jeśli chodzi o rozwijanie projektu, to najbliższe prace poświęcone będą:
- Ciągłej Integracji,
- “M” w MVC, czyli modelowi danych.
Jeśli chodzi o blogowanie, to planuję wpisy bezpośrednio związane z rozwojem kodu, a dodatkowo:
git rebase
, którego znaczenie wreszcie zrozumiałam,- Maven.
PS. Java Beans – ciekawostka lingwistyczna
W języku programowania Java istotną rolę pełnią tzw. “ziarenka”: JavaBeans oraz Enterprise JavaBeans. Dlaczego ziarenka? Otóż “Java” to w Stanach synonim słowa “kawa” (bardzo dużo kawy uprawiano na wyspie Jawie). Stąd pomysł, żeby najmniejsze samodzielne składowe aplikacji określić mianem “ziaren kawy”.

Oczywiście bardzo ciekawy wpis ale mam pytanie troszkę o coś innego. Jak zobaczyć archiwalne numery Java Magazine ?
Na tej stronie: http://www.oracle.com/technetwork/java/javamagazine/index.html klikasz “Preview Current Issue”, następnie po lewej jest zakładka “Back Issues”.