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]. Отримуємо такий результат:

Щоб запустити додаток поза межами 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]. Отримуємо такий результат:

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]:

Цього разу все вийшло.
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] — той самий вигляд, що й раніше, але цього разу з зустріччю.
У підсумку наш додаток досить добре адаптується до смартфона. Звичайно, можна було б зробити краще, але він залишається придатним для використання.





























