Skip to content

4. Експлуатація додатка

Тепер ми хочемо запустити додаток поза межами IDE, STS (для сервера) та Webstorm (для клієнта).

4.1. Розгортання веб-сервісу на сервері Tomcat

У розділі 2.11.9 ми розглянули, як створити архів war для Tomcat. Повторимо цю операцію тут. По-перше, щоб зберегти існуючі дані, ми дублюємо проект Eclipse [rdvmedecins-webapi-v3] у [rdvmedecins-webapi-v4].

  

Файл [pom.xml] змінюється наступним чином:


    <modelVersion>4.0.0</modelVersion>
    <groupId>istia.st.spring4.mvc</groupId>
    <artifactId>rdvmedecins-webapi-v4</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>rdvmedecins-webapi-v3</name>
    <description>Gestion de RV Médecins</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.0.0.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>istia.st.spring4.rdvmedecins</groupId>
            <artifactId>rdvmedecins-metier-dao-v2</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
</dependencies>

Зміни потрібно внести у двох місцях:

  • рядок 5: потрібно вказати, що буде створено архів war (Web ARchive);
  • рядки 23–27: потрібно додати залежність від артефакту [spring-boot-starter-tomcat]. Цей артефакт додає всі класи Tomcat до залежностей проєкту;
  • рядок 26: цей артефакт — [provided], тобто відповідні архіви не будуть розміщені у згенерованому WAR-файлі. Насправді ці архіви будуть розміщені на сервері Tomcat, на якому працюватиме додаток;

Крім того, необхідно налаштувати веб-додаток. За відсутності файлу [web.xml] це робиться за допомогою класу, що успадковує [SpringBootServletInitializer]:

  

Клас [ApplicationInitializer] має такий вигляд:


package rdvmedecins.web.config;

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(AppConfig.class);
    }

}
  • рядок 6: клас [ApplicationInitializer] розширює клас [SpringBootServletInitializer];
  • рядок 8: метод [configure] перевизначено (рядок 7);
  • рядок 9: надається клас [AppConfig], який налаштовує проект;

Після цього може знадобитися оновити проект Maven (мені довелося це зробити): [clic droit sur projet / Maven / Update project] або [Alt-F5].

Щоб запустити проєкт, можна вчинити так:

  • у [1] — запускаємо проєкт на одному із серверів, зареєстрованих у IDE Eclipse;
  • у [2] вибираємо [tc Server Developer], який присутній за замовчуванням. Це варіант Tomcat;

Отримуємо такий результат:

 

Це нормально. Нагадаємо, що веб-сервіс не має URL та [/] у своїх методах. При спробі використання URL та [/getAllMedecins] отримуємо таку відповідь:

 

Це нормально. Веб-сервіс захищений.

Тепер запустимо клієнт [rdvmedecins-angular-v2] у Webstorm:

У [1] вказуємо URL нового веб-сервісу [http://localhost:8080/rdvmedecins-webapi-v4]. Отримуємо такий результат:

Image

Щоб запустити додаток поза межами IDE STS, існує кілька рішень. Ось одне з них.

Завантажте версію Tomcat [http://tomcat.apache.org/download-80.cgi] (липень 2014 року):

Виберіть у [1] архів у форматі ZIP і розпакуйте його в [2]. Поверніться до STS:

  • у вкладці [Servers] клацніть правою кнопкою миші на програмі [rdvmedecins-webapi-v4] і виберіть опцію [Browse Deployment Location];
  • у [4]: скопіюйте папку [rdvmedecins-webapi-v4];
  • у [5] вставте папку [rdvmedecins-webapi-v4] у папку [webapps] сервера Tomcat;
  • у [6] запускаємо файл командного рядка [startup.bat] (при цьому сервер Tomcat, інтегрований у STS, має бути зупинений). Відкриється вікно DOS для перегляду журналів Tomcat. Вони повинні показувати, що додаток [rdvmedecins-webapi-v4] було запущено.

Щоб це перевірити, знову запускаємо клієнт Angular [rdvmedecins-angular-v2] у Webstorm:

У [1] вказуємо URL нового веб-сервісу [http://localhost:8080/rdvmedecins-webapi-v4]. Отримуємо такий результат:

Image

4.2. Розгортання клієнта Angular на сервері Tomcat

Тепер, коли веб-сервіс розгорнуто на Tomcat, ми розгорнемо клієнт Angular також на сервері. Це цілком може бути той самий сервер, на якому вже розміщено веб-сервіс. Ми оберемо саме цей варіант.

Спочатку ми дублюємо клієнт [rdvmedecins-angular-v2] у [rdvmedecins-angular-v3] і вносимо такі зміни:

  • у [1] — все було переміщено до папки [app] ;
  • у [1] було видалено папку [bower-components], яка містила різні бібліотеки CSS та JS, необхідні для проекту. Усі ці елементи було скопійовано до папки [lib] [2];
  • у [1] файл [app.html] було перейменовано на [index.html];

Файл [index.html] було змінено з урахуванням змін шляхів до використовуваних ресурсів:


<!DOCTYPE html>
<html ng-app="rdvmedecins">
<head>
  <title>RdvMedecins</title>
...
  <!-- CSS -->
  ...
  <link href="lib/bootstrap-theme.min.css" rel="stylesheet"/>
  <link href="lib/bootstrap-select.min.css" rel="stylesheet"/>
</head>
<!-- контролер [appCtrl], шаблон [app] -->
<body ng-controller="appCtrl">
<div class="container">
  ...
</div>
<!-- ядро Bootstrap JavaScript ================================================== -->
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/bootstrap-select.min.js"></script>
<script type="text/javascript" src="lib/footable.js"></script>
<!-- AngularJS -->
<script type="text/javascript" src="lib/angular.min.js"></script>
<script type="text/javascript" src="lib/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="lib/angular-route.min.js"></script>
<script type="text/javascript" src="lib/angular-translate.min.js"></script>
<script type="text/javascript" src="lib/angular-base64.min.js"></script>
<!-- модулі -->
...
<!-- сервіси -->
...
<!-- директиви -->
...
<!-- контролери -->
....
</body>
</html>

Крім того, контролер [loginCtrl] було змінено, щоб він вказував на правильний сервер, аби користувачеві не довелося вводити свій URL:


// повноваження
app.serverUrl = "http://localhost:8080/rdvmedecins-webapi-v4";
app.username = "admin";
app.password = "admin";

Тепер запустимо файл [index.html]:

Потім підключімося до веб-сервісу. Все має працювати. Переконавшись у цьому, зупинімо сервер Tomcat. Ми будемо використовувати вбудований сервер STS.

У STS скопіюємо весь вміст папки [rdvmedecins-angular-v3/app] у папку [webapp] проекту [rdvmedecins-webapi-v4] (вкладка Navigator) [1]:

Після цього запустимо [2], сервер VMware з STS, а потім запитаємо URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:

У [3] виникла проблема з правами доступу. Це не дивно, оскільки ми захистили веб-сервіс. Потрібно вказати, що доступ до файлу [/app/index.html] є вільним. Повернемося до Eclipse:

  

Нагадаємо, що права доступу були визначені у класі [SecurityConfig]. Змінимо його наступним чином:


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // CSRF
        http.csrf().disable();
        // пароль передається у заголовку Authorization: Basic xxxx
        http.httpBasic();
        // метод HTTP OPTIONS має бути дозволений для всіх
        http.authorizeRequests() //
                .antMatchers(HttpMethod.OPTIONS, "/", "/**").permitAll();
        // папка [app] доступна для всіх
        http.authorizeRequests() //
                .antMatchers(HttpMethod.GET, "/app", "/app/**").permitAll();
        // лише роль ADMIN може використовувати додаток
        http.authorizeRequests() //
                .antMatchers("/", "/**") // усі URL
                .hasRole("ADMIN");
}
  • рядки 11–12: надаємо всім користувачам право на читання папки [app] та її вмісту. Для цього скористаємося попередніми рядками як зразком.

Тепер перезапустимо сервер Tomcat для STS, а потім знову звернемося до URL та [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:

Image

Цього разу все вийшло.

4.3. Заголовки CORS

Можливо, ви пам’ятаєте, що нам довелося докласти чимало зусиль, щоб впоратися із заголовками CORS. У попередньому прикладі:

  • веб-сервіс знаходиться за адресою URL [http://localhost:8080/rdvmedecins-webapi-v4];
  • клієнт HTML знаходиться на сервері URL [http://localhost:8080/rdvmedecins-webapi-v4/app];

Отже, клієнт HTML і веб-сервіс знаходяться на одному сервері [http://localhost:8080]. У цьому випадку конфліктів CORS немає, оскільки вони виникають лише тоді, коли клієнт і сервер знаходяться не в одному домені. Це можна перевірити. Повернемося до STS:

  

Генерація заголовків CORS контролюється булевим значенням, визначеним у класі [ApplicationModel]:


    // дані конфігурації
    private boolean CORSneeded = true;

Ми встановлюємо значення вищезазначеного булевого параметра на false, перезапускаємо веб-сервіс і знову надсилаємо запит на URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]. Бачимо, що додаток працює.

4.4. Розгортання клієнта Angular на планшеті з Android

Інструмент [Phonegap] [http://phonegap.com/] дозволяє створити виконуваний файл для мобільних пристроїв (Android, IoS, Windows 8, ...) на основі додатка HTML / JS / CSS. Існують різні способи досягнення цієї мети. Ми використовуємо найпростіший: онлайн-інструмент на сайті Phonegap [http://build.phonegap.com/apps].

  • перед [1], можливо, вам доведеться створити обліковий запис;
  • на [1] починаємо роботу;
  • на [2] обираємо безкоштовний тариф, який дозволяє створити лише один додаток Phonegap;
  • у [3] завантажуємо архів із додатком [4] (папка [app], створена у пункті 4.2, упакована в архів);
  • у [5], надайте назву додатку;
  • у файлі [6] — створюється програма. Ця операція може тривати 1 хвилину. Зачекайте, доки піктограми різних мобільних платформ не покажуть, що створення завершено;
  • були згенеровані лише бінарні файли для Android ([7]) та Windows ([8]);
  • натисніть на [7], щоб завантажити бінарний файл для Android;
  • у [9] завантажений бінарний файл [apk];

Запустіть емулятор [GenyMotion] для планшета на базі Android (див. розділ 6.4):

 

Вище показано запуск емулятора планшета з Android версії API 16. Після запуску емулятора

  • розблокуйте його, потягнувши засувку (якщо вона є) убік, а потім відпустивши її;
  • за допомогою миші перетягніть завантажений файл [PGBuildApp-debug.apk] і відпустіть його на емуляторі. Після цього програма буде встановлена та запущена;

Необхідно змінити URL на [1]. Для цього у командному вікні введіть команду [ipconfig] (рядок 1 нижче), яка відобразить різні адреси IP вашого комп’ютера:


C:\Users\Serge Tahé>ipconfig

Configuration IP de Windows


Carte réseau sans fil Connexion au réseau local* 15 :

   Statut du média. . . . . . . . . . . . : Média déconnecté
   Suffixe DNS propre à la connexion. . . :

Carte Ethernet Connexion au réseau local :

   Suffixe DNS propre à la connexion. . . : ad.univ-angers.fr
   Adresse IPv6 de liaison locale. . . . .: fe80::698b:455a:925:6b13%4
   Adresse IPv4. . . . . . . . . . . . . .: 172.19.81.34
   Masque de sous-réseau. . . . . . . . . : 255.255.0.0
   Passerelle par défaut. . . . . . . . . : 172.19.0.254

Carte réseau sans fil Wi-Fi :

   Statut du média. . . . . . . . . . . . : Média déconnecté
   Suffixe DNS propre à la connexion. . . :

...

Запишіть або адресу Wi-Fi IP (рядки 6–9), або адресу в локальній мережі IP (рядки 11–17). Потім використовуйте цю адресу IP у налаштуваннях веб-сервера URL:

 

Після цього підключіться до веб-сервісу:

Перевірте роботу додатка на емуляторі. Він має працювати. На стороні сервера можна дозволити або заборонити заголовки CORS у класі [ApplicationModel]:


    // дані конфігурації
    private boolean CORSneeded = false;

Для додатка Android це не має значення. Він не виконується в браузері. А вимога щодо заголовків CORS походить саме від браузера, а не від сервера.

4.5. Розгортання клієнта Angular на емуляторі смартфона Android

Повторюємо попередню операцію з емулятором смартфона. Хочемо перевірити, як поводиться наш клієнт на невеликих екранах:

  • у [1] запускаємо емулятор смартфона;
  • на [2] та [3] панель навігації була згорнута в меню;
  • у [4] відбувається вхід у систему;
  • у [5] список і календар розташовані один під одним, а не поруч;
  • у [6] запитується календар;
  • у [7] екран замалий, тому частина часових проміжків прихована. Цю роботу виконала бібліотека [footable];
  • у [8] — той самий вигляд, що й раніше, але цього разу з зустріччю.

У підсумку наш додаток досить добре адаптується до смартфона. Звичайно, можна було б зробити краще, але він залишається придатним для використання.