Відмінності war та jar-файлів
Фактично jar-бібліотека – це просто zip архів, що зрозуміло з його імені: Java Archive. Найчастіше він має чотири складові:
- скомпільовані класи;
- ресурси: properties-файли тощо;
- маніфест MANIFEST.MF;
- інші jar-бібліотеки (рідко).
Вигляд типової структури такого архіву:
META-INF/
MANIFEST.MF
com/
javarush/
MyApplication.class
application.properties
Тепер давай розглянемо типовий war-файл. До речі, war – не від слова війна, а від Web Archive. Структура war-файлу зазвичай складніша. Найчастіше він складається з двох частин:
- Java складова
- скомпільовані класи
- ресурси для java-класів: properties-файли тощо
- інші jar-бібліотеки (часто)
- маніфест MANIFEST.MF
- Web складова
- web-xml – дескриптор розгортання вебсервісу
- jsp-сервелети
- статичні веб-ресурси: HTML, CSS, JS-файли
Приклад типового war-файлу:
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
jsp/
helloWorld.jsp
classes/
static/
templates/
application.properties
lib/
// *.jar files as libs
Важливо! jar-файл може запустити просто java-машину, а для запуску war-файлу його потрібно завантажити на вебсервер. Самостійно він не запускається.
Плагін створення war-файлу за допомогою maven-war-plugin
Уявімо, що у нас є простий вебпроєкт. Нехай проєкт визначається такою структурою файлів. Як його зібрати?
|-- pom.xml
`-- src
`-- main
|-- java
| `-- com
| `-- example
| `-- projects
| `-- SampleAction.java
|-- resources
| `-- images
| `-- sampleimage.jpg
`-- webapp
|-- WEB-INF
| `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp
По-перше, нам потрібно вказати Maven, зібрати все це у вигляді war-файлу. Для цього є тег <package>, ось приклад:
<project>
...
<groupId>com.example.projects</groupId>
<artifactId>simple-war</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Simple War Project</name>
<url>http://javarush.com</url>
...
</project>
По-друге, нам потрібно підключити плагін maven-war-plugin. Приклад:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
Тут ми просто вказуємо плагін, який у майбутньому можна конфігурувати. Також за допомогою тега webappDirectory перевизначаємо директорію, до якої буде розгорнено проєкт. Давай розглянемо детальніше, про що йдеться.
Плагіну можна встановити два режими складання (два види goal):
- war:war
- war:exploded
У першому випадку підсумковий war-файл просто кладеться до папки target і має ім'я <artifactId>-<version>.war.
Але можна "попросити" плагін, щоб у підсумкову папку вміст war-файлу було розміщено в тому стані, в якому він буде розпакований вебсервером у себе всередині. Для цього використовується goal war:exploded.
Другий підхід використовується часто, якщо ти запускаєш або дебажиш проєкт прямо з Intellij IDEA.
До речі, тег webappDirectory у прикладі вище дозволяє перевизначити директорію, куди буде розпаковано твій war-файл при складанні в режимі war:exploded.
Про інші налаштування плагіна можна дізнатися з його офіційної сторінки.
Складання вебзастосунків на основі SpringBoot
Давай розберемо якийсь реальний приклад складання проєкту. Подивимося на програму на основі SpringBoot.
Крок перший. Створи порожній Maven web-проект за допомогою IDEA.
Крок другий. Додай до його pom.xml залежно від Spring.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Крок третій. Створи клас com.javarush.spring.MainController. Його потрібно розмістити в папці src/main/java:
@Controller
public class MainController {
@GetMapping("/")
public String viewIndexPage(Model model) {
model.addAttribute("header", "Maven Generate War");
return "index";
}
}
Тут описано 3 речі. По-перше, анотація @Controller показує фреймворку SpringBoot, що цей клас буде використовуватися для обслуговування вхідних веб-запитів.
По-друге, анотація @GetMapping вказує, що наш метод буде викликатися для обслуговування GET-запиту на кореневий URI - /
По-третє, метод повертає рядок "index". Це говорить фреймворку SpringBoot, що як відповідь потрібно віддати вміст файлу index.html.
Крок четвертий. Потрібно додати до проєкту файл index.html з таким вмістом:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
<!-- Bootstrap core CSS -->
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">
JavaRush Tutorial
</a>
</div>
</nav>
<div class="container">
<h1>[[${header}]]</h1>
</div>
</body>
</html>
Це не просто HTML. Перед тим, як його вміст віддадуть клієнту, його буде модифіковано на сервері фреймворком Thymeleaf. У цей файл вбудовані спеціальні теги, які дозволяють бібліотеці Thymeleaf обробляти та модифікувати вміст сторінки.
Червоним відображені теги, які будуть оброблені бібліотекою Thymeleaf, зеленим – стилі CSS-бібліотеки Bootstrap.
Крок п'ятий. Вказуємо плагін у pom.xml:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
Трохи переоцінив власні сили. Щоб повністю розібрати простий приклад, потрібно багато часу. Але ти можеш завантажити повний код проєкту з GitHub та спробувати розібратися у ньому самостійно. До речі, відсотків 80% свого робочого часу ти робитимеш саме це :)
Повний код ти можеш завантажити за цим посиланням у GitHub.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ