Skip to content

16. Wprowadzenie do Springa MVC

16.1. Rola Springa MVC w aplikacji internetowej

Umieśćmy Spring MVC w kontekście tworzenia aplikacji internetowej. Najczęściej będzie ona oparta na architekturze wielowarstwowej, takiej jak poniższa:

  • warstwa [Web] stanowi warstwę kontaktową z użytkownikiem aplikacji internetowej. Użytkownik ten wchodzi w interakcję z aplikacją internetową za pośrednictwem stron internetowych wyświetlanych w przeglądarce. To właśnie w tej warstwie znajduje się Spring MVC i wyłącznie w tej warstwie;
  • warstwa [métier] realizuje reguły biznesowe aplikacji, takie jak obliczanie wynagrodzenia lub faktury. Warstwa ta wykorzystuje dane pochodzące od użytkownika za pośrednictwem warstwy [Web] oraz dane z warstw SGBD za pośrednictwem warstwy [DAO];
  • Warstwa [DAO] (Data Access Objects), warstwa [ORM] (Object Relational Mapper) oraz sterownik JDBC zarządzają dostępem do danych z warstwy SGBD. Warstwa [ORM] stanowi pomost między obiektami obsługiwanymi przez warstwę [DAO] a wierszami i kolumnami tabel w relacyjnej bazie danych. Specyfikacja o nazwie JPA (Java Persistence API) pozwala na abstrakcję od używanego ORM, o ile ten ostatni implementuje te specyfikacje. Tak będzie w przypadku niniejszego samouczka, dlatego od tej pory będziemy nazywać warstwę ORM warstwą JPA;
  • integracja warstw odbywa się za pośrednictwem frameworka Spring;

16.2. Model rozwoju Spring MVC

Spring MVC implementuje model architektury zwany MVC (Model – Widok – Kontroler) w następujący sposób:

Przetwarzanie żądania klienta przebiega w następujący sposób:

  1. żądanie – żądane obiekty URL mają postać http://machine:port/contexte/Action/param1/param2/....?p1=v1&p2=v2&.... [Front Controller] wykorzystuje plik konfiguracyjny lub adnotacje Java do „przekierowania” żądania do właściwego kontrolera i właściwej akcji w ramach tego kontrolera. W tym celu wykorzystuje pole [Action] z URL. Pozostała część URL i [/param1/param2/...] składa się z opcjonalnych parametrów, które zostaną przekazane do akcji. C w MVC to w tym przypadku ciąg znaków [Front Controller, Contrôleur, Action]. Jeśli żaden kontroler nie jest w stanie obsłużyć żądanej akcji, serwer WWW odpowie, że żądana akcja URL nie została znaleziona.
  1. Przetwarzanie
      • (ciąg dalszy)
    • Wybrana akcja może wykorzystać parametry parami, które przekazał jej [Front Controller]. Mogą one pochodzić z kilku źródeł:
      • ze ścieżki [/param1/param2/...] pliku URL,
      • z parametrów [p1=v1&p2=v2] akcji URL,
      • z parametrów przesłanych przez przeglądarkę wraz z żądaniem;
    • podczas przetwarzania żądania użytkownika akcja może wymagać warstwy [métier] [2b]. Po przetworzeniu żądania klienta może ono wywołać różne odpowiedzi. Klasycznym przykładem jest:
      • strona błędu, jeśli żądanie nie mogło zostać poprawnie przetworzone
      • w przeciwnym razie strona potwierdzenia
    • akcja żąda wyświetlenia określonego widoku [3]. Widok ten wyświetli dane, które nazywamy modelem widoku. To właśnie litera M w MVC. Akcja utworzy ten model M [2c] i zażąda wyświetlenia widoku V [3];
  1. odpowiedź – wybrany widok V wykorzystuje model M utworzony przez akcję do zainicjowania dynamicznych części odpowiedzi HTML, którą musi wysłać do klienta, a następnie wysyła tę odpowiedź.

W przypadku usługi internetowej / jSON powyższa architektura ulega niewielkiej modyfikacji:

  • w [4a] model, który jest klasą Java, jest przekształcany w ciąg znaków jSON przez bibliotekę jSON;
  • w [4b] ten ciąg znaków jSON jest wysyłany do przeglądarki;

Teraz wyjaśnijmy związek między architekturą internetową MVC a architekturą warstwową. W zależności od definicji modelu te dwie koncepcje mogą być ze sobą powiązane lub nie. Weźmy na przykład jednowarstwową aplikację internetową Spring MVC:

Jeśli zaimplementujemy warstwę [Web] przy użyciu Springa MVC, otrzymamy wprawdzie architekturę internetową MVC, ale nie będzie to architektura wielowarstwowa. W tym przypadku warstwa [web] zajmie się wszystkim: prezentacją, logiką biznesową oraz dostępem do danych. Zadania te będą realizowane przez akcje.

Rozważmy teraz wielowarstwową architekturę internetową:

Warstwa [Web] może zostać zaimplementowana bez frameworka i bez stosowania się do modelu MVC. Mamy więc architekturę wielowarstwową, ale warstwa internetowa nie implementuje modelu MVC.

Na przykład w środowisku .NET warstwa [Web]może być zaimplementowana przy użyciu ASP.NET i MVC, co daje architekturę warstwową z warstwą [Web] typu MVC. Po wykonaniu tej czynności można zastąpić tę warstwę ASP.NET MVC klasyczną warstwą ASP.NET (WebForms), zachowując pozostałe elementy (biznesową, DAO, ORM) bez zmian. Otrzymujemy wówczas architekturę warstwową z warstwą [Web], która nie jest już typu MVC.

W MVC stwierdziliśmy, że model M odpowiada widokowi V, c.a.d, czyli zbiorowi danych wyświetlanych przez widok V. Podano kolejną definicję modelu M dla MVC:

Wielu autorów uważa, że to, co znajduje się po prawej stronie warstwy [Web], tworzy model M modelu MVC. Aby uniknąć niejasności, można mówić o:

  • o modelu domeny, gdy mamy na myśli wszystko, co znajduje się po prawej stronie warstwy [Web]
  • o modelu widoku, gdy mamy na myśli dane wyświetlane przez widok V

W dalszej części termin „model M” będzie odnosił się wyłącznie do modelu widoku V.

16.3. Projekt internetowy / jSON z wykorzystaniem Springa MVC

Strona [http://spring.io/guides] zawiera samouczki dla początkujących, pozwalające zapoznać się z ekosystemem Spring. Skorzystamy z jednego z nich, aby poznać konfigurację Maven niezbędną dla projektu Spring MVC.

16.3.1. Projekt demonstracyjny

  • w [1] importujemy jeden z przewodników Spring;
  • w [2] wybieramy przykład [Rest Service];
  • w [3] wybieramy projekt Maven;
  • w [4] wybieramy ostateczną wersję przewodnika;
  • w [5] zatwierdzamy;
  • w [6] – zaimportowany projekt;

Usługi internetowe dostępne za pośrednictwem standardowych interfejsów URL i dostarczające tekst jSON są często nazywane usługami REST (REpresentational State Transfer). Usługa jest określana jako RESTful, jeśli spełnia określone zasady.

Przyjrzyjmy się teraz zaimportowanemu projektowi, a najpierw jego konfiguracji Maven.

16.3.2. Konfiguracja Maven

Plik [pom.xml] ma następującą treść:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-rest-service</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.2.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <start-class>hello.Application</start-class>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>
  • wiersze 6–8: właściwości projektu Maven. Brakuje tagu [<packaging>] określającego typ pliku generowanego przez kompilację Maven. W przypadku jego braku stosowany jest typ [jar]. Aplikacja jest zatem aplikacją konsolową, a nie aplikacją internetową, w przypadku której pakiet miałby typ [war];
  • wiersze 10–14: projekt Maven ma projekt nadrzędny o nazwie [spring-boot-starter-parent]. To właśnie on definiuje większość zależności projektu. Mogą one być wystarczające, w którym to przypadku nie dodaje się żadnych nowych, lub mogą być niewystarczające, w którym to przypadku dodaje się brakujące zależności;
  • wiersze 17–20: artefakt [spring-boot-starter-web] zawiera biblioteki niezbędne dla projektu Spring o nazwie MVC, będącego serwisem internetowym, w którym nie generowane są widoki. Ten artefakt zawiera bardzo dużą liczbę bibliotek, w tym biblioteki wbudowanego serwera Tomcat. To właśnie na tym serwerze będzie uruchamiana aplikacja;

Biblioteki dostarczane w ramach tej konfiguracji są bardzo liczne:

Powyżej widoczne są trzy archiwa serwera Tomcat.

16.3.3. Architektura serwisu Spring [web / jSON]

W przypadku serwisu internetowego / jSON, Spring MVC implementuje model MVC w następujący sposób:

  • w [4a] model, który jest klasą Java, jest przekształcany w ciąg znaków jSON przez bibliotekę jSON;
  • w [4b] ten ciąg znaków jSON jest wysyłany do przeglądarki;

16.3.4. Kontroler C

  

Zaimportowana aplikacja posiada następujący kontroler:


package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}
  • wiersz 9: adnotacja [@RestController] sprawia, że klasa [GreetingController] staje się kontrolerem Springa, co oznacza, że jej metody są zarejestrowane do obsługi obiektów typu URL. Widzieliśmy już podobną adnotację [@Controller]. Wynikiem działania metod tego kontrolera był typ [String], który stanowił nazwę widoku do wyświetlenia. Tutaj jest inaczej. Metody kontrolera typu [@RestController] zwracają obiekty, które są serializowane w celu wysłania do przeglądarki. Typ przeprowadzanej serializacji zależy od konfiguracji Springa MVC. W tym przypadku zostaną one zserializowane do formatu jSON. To właśnie obecność biblioteki jSON wśród zależności projektu sprawia, że Spring Boot, poprzez autokonfigurację, skonfiguruje projekt w ten sposób;
  • wiersz 14: adnotacja [@RequestMapping] wskazuje na URL, który jest przetwarzany przez metodę, w tym przypadku URL [/greeting];
  • wiersz 15: adnotację [@RequestParam] wyjaśniliśmy już wcześniej. Wynikiem zwracanym przez metodę jest obiekt typu [Greeting].
  • wiersz 12: liczba całkowita typu long o charakterze atomowym. Oznacza to, że obsługuje współbieżność dostępu. Kilka wątków może jednocześnie próbować zwiększyć wartość zmiennej [counter]. Odbędzie się to poprawnie. Wątek może odczytać wartość licznika dopiero wtedy, gdy wątek dokonujący modyfikacji zakończył swoją operację.

16.3.5. Model M

Model M wygenerowany przez poprzednią metodę to następujący obiekt [Greeting]:

  

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

Transformacja jSON tego obiektu utworzy ciąg znaków {"id":n,"content":"tekst"}. Ostatecznie ciąg znaków jSON wygenerowany przez metodę kontrolera będzie miał postać:

{"id":2,"content":"Hello, World!"}

lub

{"id":2,"content":"Hello, John!"}

16.3.6. Wykonanie

  

Klasa [Application.java] jest klasą wykonywalną projektu. Jej kod wygląda następująco:


package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Ten kod omówiliśmy już w poprzednim przykładzie. Uruchommy projekt:

 

Otrzymujemy następujące logi konsoli:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.9.RELEASE)

2014-11-28 15:22:55.005  INFO 3152 --- [           main] hello.Application                        : Starting Application on Gportpers3 with PID 3152 (started by ST in D:\data\istia-1415\spring mvc\dvp-final\gs-rest-service)
2014-11-28 15:22:55.046  INFO 3152 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@62e136d3: startup date [Fri Nov 28 15:22:55 CET 2014]; root of context hierarchy
2014-11-28 15:22:55.762  INFO 3152 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-11-28 15:22:56.567  INFO 3152 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-11-28 15:22:56.738  INFO 3152 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2014-11-28 15:22:56.740  INFO 3152 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.56
2014-11-28 15:22:56.869  INFO 3152 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-11-28 15:22:56.870  INFO 3152 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1827 ms
2014-11-28 15:22:57.478  INFO 3152 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-11-28 15:22:57.481  INFO 3152 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2014-11-28 15:22:57.685  INFO 3152 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-28 15:22:57.879  INFO 3152 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/greeting],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public hello.Greeting hello.GreetingController.greeting(java.lang.String)
2014-11-28 15:22:57.884  INFO 3152 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-11-28 15:22:57.885  INFO 3152 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-11-28 15:22:57.906  INFO 3152 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] do obsługi typu [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-28 15:22:57.907  INFO 3152 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] do obsługi typu [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-28 15:22:58.231  INFO 3152 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-11-28 15:22:58.318  INFO 3152 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-11-28 15:22:58.319  INFO 3152 --- [           main] hello.Application                        : Started Application in 3.788 seconds (JVM running for 4.424)
  • wiersz 13: serwer Tomcat uruchamia się na porcie 8080 (wiersz 12);
  • wiersz 17: serwlet [DispatcherServlet] jest obecny;
  • wiersz 20: wykryto metodę [GreetingController.greeting];

Aby przetestować aplikację internetową, wysyłamy żądanie do serwletu URL [http://localhost:8080/greeting]:

 

Otrzymujemy oczekiwany ciąg znaków jSON. Warto przyjrzeć się nagłówkom HTTP wysyłanym przez serwer. W tym celu użyjemy rozszerzenia do przeglądarki Chrome o nazwie [Advanced Rest Client] (Chrome / Ctrl-T / Menu [Applications] / [Advanced Rest Client] – patrz załączniki, punkt 23.11):

  • w [1], żądany plik URL;
  • w [2] zastosowano metodę GET;
  • w [3] – odpowiedź jSON;
  • w przypadku [4] serwer poinformował, że wysyła odpowiedź w formacie jSON;
  • w [5] żądana jest ta sama odpowiedź URL, ale tym razem z POST;
  • w [7] informacje są wysyłane do serwera w postaci [urlencoded];
  • w [6] – parametr „name” wraz z jego wartością;
  • w [8] przeglądarka informuje serwer, że przesyła mu informacje [urlencoded];
  • w [9] – odpowiedź serwera jSON;

16.3.7. Tworzenie archiwum wykonywalnego

Teraz tworzymy archiwum wykonywalne:

  • w [1]: uruchamiamy cel Maven;
  • w [2]: występują dwa cele (goals): [clean] w celu usunięcia folderu [target] z projektu Maven oraz [package] w celu jego ponownego wygenerowania;
  • w [3]: wygenerowany folder [target] zostanie umieszczony w tym folderze;
  • w [4]: generowany jest cel;

W logach wyświetlanych w konsoli ważne jest, aby pojawiła się wtyczka [spring-boot-maven-plugin]. To właśnie ona generuje archiwum wykonywalne (patrz [pom.xml] poniżej):


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
</build>
[INFO] --- spring-boot-maven-plugin:1.1.0.RELEASE:repackage (default) @ gs-rest-service ---

W konsoli należy przejść do wygenerowanego folderu:


D:\Temp\wksSTS\gs-rest-service\target>dir
 ...
11/06/2014  15:30    <DIR>          classes
11/06/2014  15:30    <DIR>          generated-sources
11/06/2014  15:30        11 073 572 gs-rest-service-0.1.0.jar
11/06/2014  15:30             3 690 gs-rest-service-0.1.0.jar.original
11/06/2014  15:30    <DIR>          maven-archiver
11/06/2014  15:30    <DIR>          maven-status
...
  • wiersz 5: wygenerowany plik archiwum;

Archiwum to uruchamia się w następujący sposób:


D:\Temp\wksSTS\gs-rest-service-complete\target>java -jar gs-rest-service-0.1.0.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.0.RELEASE)

2014-06-11 15:32:47.088  INFO 4972 --- [           main] hello.Application
                  : Starting Application on Gportpers3 with PID 4972 (D:\Temp\wk
sSTS\gs-rest-service-complete\target\gs-rest-service-0.1.0.jar started by ST in
D:\Temp\wksSTS\gs-rest-service-complete\target)
...

Teraz, gdy aplikacja internetowa została uruchomiona, można ją wywołać za pomocą przeglądarki:

 

16.3.8. Wdrożenie aplikacji na serwerze Tomcat

Podobnie jak w przypadku poprzedniego projektu, modyfikujemy plik [pom.xml] w następujący sposób:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-rest-service</artifactId>
    <version>0.1.0</version>
    <packaging>war</packaging>

    ...
</project>
  • wiersz 9: należy wskazać, że zamierzamy wygenerować archiwum WAR (Web ARchive);

Należy również skonfigurować aplikację internetową. W przypadku braku pliku [web.xml] odbywa się to za pomocą klasy dziedziczącej po [SpringBootServletInitializer]:

  

Klasa [ApplicationInitializer] ma następującą postać:


package hello;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

public class ApplicationInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

}
  • wiersz 6: klasa [ApplicationInitializer] rozszerza klasę [SpringBootServletInitializer];
  • wiersz 9: metoda [configure] została ponownie zdefiniowana (wiersz 8);
  • wiersz 10: podano klasę konfigurującą projekt;

Aby uruchomić projekt, można postępować w następujący sposób:

  • w [1-2] uruchamia się projekt na jednym z serwerów zarejestrowanych w IDE Eclipse;

Po wykonaniu tej czynności można wywołać URL [http://localhost:8080/gs-rest-service/greeting/?name=Mitchell] w przeglądarce:

 

16.4. Conclusion

Wprowadziliśmy rodzaj projektów Spring o nazwie MVC, w których aplikacja internetowa wysyła strumień jSON do przeglądarki. Teraz opracujemy aplikację internetową / jSON w celu udostępnienia w sieci bazy danych [dbproduitscategories] omówionej w poprzednich rozdziałach.