diff --git a/2021-03/spring-16-ajax/ajax-demo.html b/2021-03/spring-16-ajax/ajax-demo.html
new file mode 100644
index 00000000..b71de6c2
--- /dev/null
+++ b/2021-03/spring-16-ajax/ajax-demo.html
@@ -0,0 +1,84 @@
+
+
+
+ Технологии JS для отправки запросов
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/pom.xml b/2021-03/spring-16-ajax/spring-ajax-demo/pom.xml
new file mode 100644
index 00000000..38e975ff
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/pom.xml
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-ajax-demo
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
+ 11
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.webjars
+ jquery
+ 3.5.1
+
+
+
+
+ com.h2database
+ h2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.20
+ provided
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/Main.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..e2779e96
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,13 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/domain/Person.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..56404ae3
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/domain/Person.java
@@ -0,0 +1,22 @@
+package ru.otus.spring.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "persons")
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/page/PersonPagesController.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/page/PersonPagesController.java
new file mode 100644
index 00000000..0f3a2e76
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/page/PersonPagesController.java
@@ -0,0 +1,15 @@
+package ru.otus.spring.page;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
+public class PersonPagesController {
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ model.addAttribute("keywords", "list users in Omsk, omsk, list users, list users free");
+ return "list";
+ }
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java
@@ -0,0 +1,11 @@
+package ru.otus.spring.repostory;
+
+import org.springframework.data.repository.CrudRepository;
+import ru.otus.spring.domain.Person;
+
+import java.util.List;
+
+public interface PersonRepository extends CrudRepository {
+
+ List findAll();
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/PersonController.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/PersonController.java
new file mode 100644
index 00000000..26fee19f
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/PersonController.java
@@ -0,0 +1,23 @@
+package ru.otus.spring.rest;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import ru.otus.spring.repostory.PersonRepository;
+import ru.otus.spring.rest.dto.PersonDto;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RequiredArgsConstructor
+@RestController
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/api/persons")
+ public List getAllPersons() {
+ return repository.findAll().stream().map(PersonDto::toDto)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java
new file mode 100644
index 00000000..ee966a8e
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 Russian Post
+ *
+ * This source code is Russian Post Confidential Proprietary.
+ * This software is protected by copyright. All rights and titles are reserved.
+ * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software.
+ * Otherwise this violation would be treated by law and would be subject to legal prosecution.
+ * Legal use of the software provides receipt of a license from the right name only.
+ */
+package ru.otus.spring.rest.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import ru.otus.spring.domain.Person;
+
+@Data
+@AllArgsConstructor
+public class PersonDto {
+
+ private long id = -1;
+ private String name;
+
+ public static PersonDto toDto(Person person) {
+ return new PersonDto(person.getId(), person.getName());
+ }
+}
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/application.yml b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..21e39b30
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/application.yml
@@ -0,0 +1,11 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ initialization-mode: always
+
+ jpa:
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
\ No newline at end of file
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/data.sql b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/data.sql
new file mode 100644
index 00000000..e60c79ca
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/data.sql
@@ -0,0 +1 @@
+INSERT INTO persons (name) VALUES ('Pushkin'), ('Lermontov')
\ No newline at end of file
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/schema.sql b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/schema.sql
new file mode 100644
index 00000000..7771dc1b
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/schema.sql
@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS persons;
+
+CREATE TABLE persons (
+ id BIGSERIAL,
+ name VARCHAR(250),
+
+ PRIMARY KEY (id)
+);
\ No newline at end of file
diff --git a/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/templates/list.html b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/templates/list.html
new file mode 100644
index 00000000..3d37dce1
--- /dev/null
+++ b/2021-03/spring-16-ajax/spring-ajax-demo/src/main/resources/templates/list.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ List of all persons
+
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+
+
+
+
+
+
+
+
+
+