diff --git a/2024-01/spring-18-view/.gitignore b/2024-01/spring-18-view/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/pom.xml b/2024-01/spring-18-view/pom.xml
new file mode 100644
index 00000000..f2ad9bdf
--- /dev/null
+++ b/2024-01/spring-18-view/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view
+ 1.0
+
+ pom
+
+
+ spring-mvc-view-exercise
+ spring-mvc-view-demo
+ spring-mvc-view-solution1
+ spring-mvc-view-solution2
+ spring-mvc-view-solution3
+ spring-mvc-view-solution4
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/.gitignore b/2024-01/spring-18-view/spring-mvc-view-demo/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/pom.xml b/2024-01/spring-18-view/spring-mvc-view-demo/pom.xml
new file mode 100644
index 00000000..4b83be3c
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/pom.xml
@@ -0,0 +1,81 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-demo
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..6ec3d275
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,14 @@
+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);
+ System.out.printf("Чтобы перейти на страницу сайта открывай: %n%s%n",
+ "http://localhost:8080");
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/config/LocalizationConfig.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/config/LocalizationConfig.java
new file mode 100644
index 00000000..fa2743ac
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/config/LocalizationConfig.java
@@ -0,0 +1,34 @@
+package ru.otus.spring.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+import java.util.Locale;
+
+@Configuration
+public class LocalizationConfig implements WebMvcConfigurer {
+
+ @Bean(name = "localeResolver")
+ public LocaleResolver localeResolver() {
+ var resolver = new CookieLocaleResolver("locale");
+ resolver.setDefaultLocale(new Locale("en"));
+ return resolver;
+ }
+
+ @Bean
+ public LocaleChangeInterceptor localeChangeInterceptor() {
+ var localeChangeInterceptor = new LocaleChangeInterceptor();
+ localeChangeInterceptor.setParamName("lang");
+ return localeChangeInterceptor;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(localeChangeInterceptor());
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..57419775
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,47 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.dto.PersonDto;
+import ru.otus.spring.repostory.PersonRepository;
+
+import jakarta.validation.Valid;
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ Person person = repository.findById(id).orElseThrow(NotFoundException::new);
+ model.addAttribute("person", person);
+ return "edit";
+ }
+
+ @PostMapping("/edit")
+ public String savePerson(@Valid @ModelAttribute("person") PersonDto person,
+ BindingResult bindingResult, Model model) {
+ if (bindingResult.hasErrors()) {
+ return "edit";
+ }
+ repository.save(person.toDomainObject());
+ return "redirect:/";
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/dto/PersonDto.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/dto/PersonDto.java
new file mode 100644
index 00000000..07f0e7e7
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/dto/PersonDto.java
@@ -0,0 +1,27 @@
+package ru.otus.spring.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import ru.otus.spring.domain.Person;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+
+@Data
+@AllArgsConstructor
+public class PersonDto {
+
+ private long id;
+
+ @NotBlank(message = "{name-field-should-not-be-blank}")
+ @Size(min = 2, max = 10, message = "{name-field-should-has-expected-size}")
+ private String name;
+
+ public Person toDomainObject(){
+ return new Person(id, name);
+ }
+
+ public static PersonDto fromDomainObject(Person person) {
+ return new PersonDto(person.getId(), person.getName());
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-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/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..ec0f5ba6
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/application.yml
@@ -0,0 +1,22 @@
+spring:
+ messages:
+ encoding: UTF-8
+
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages.properties b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages.properties
new file mode 100644
index 00000000..3a6a2587
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages.properties
@@ -0,0 +1,13 @@
+lang-switcher-header=Select language
+en-lang-switch-button-caption=Language - EN
+ru-lang-switch-button-caption=Language - RU
+persons-table-header=Persons:
+persons-table-column-action=Action
+person-field-id=ID
+person-field-name=Name
+edit-button-caption=Edit
+person-form-header=Person Info:
+save-button-caption=Save
+cancel-button-caption=Cancel
+name-field-should-not-be-blank=Name field should not be blank
+name-field-should-has-expected-size=Name field should be between 2 and 10 characters
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_en.properties b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_en.properties
new file mode 100644
index 00000000..35de6541
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_en.properties
@@ -0,0 +1,13 @@
+lang-switcher-header=Select language
+en-lang-switch-button-caption=Language - EN
+ru-lang-switch-button-caption=Language - RU
+persons-table-header=Persons:
+persons-table-column-action=Action
+person-field-column-id=ID
+person-field-name=Name
+edit-button-caption=Edit
+person-form-header=Person Info:
+save-button-caption=Save
+cancel-button-caption=Cancel
+name-field-should-not-be-blank=Name field should not be blank
+name-field-should-has-expected-size=Name field should be between 2 and 10 characters
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_ru.properties b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_ru.properties
new file mode 100644
index 00000000..fadc8fa5
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/messages_ru.properties
@@ -0,0 +1,13 @@
+lang-switcher-header=\u0412\u044B\u0431\u043E\u0440 \u044F\u0437\u044B\u043A\u0430
+en-lang-switch-button-caption=\u042F\u0437\u044B\u043A - EN
+ru-lang-switch-button-caption=\u042F\u0437\u044B\u043A - RU
+persons-table-header=\u041F\u0451\u0440\u0441\u043E\u043D\u044B:
+persons-table-column-action=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+person-field-id=\u0410\u0439\u0414\u0438
+person-field-name=\u0418\u043C\u044F
+edit-button-caption=\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C
+person-form-header=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u043F\u0451\u0440\u0441\u043E\u043D\u0435:
+save-button-caption=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
+cancel-button-caption=\u041E\u0442\u043C\u0435\u043D\u0430
+name-field-should-not-be-blank=\u0418\u043C\u044F \u043D\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C
+name-field-should-has-expected-size=\u0414\u043B\u0438\u043D\u0430 \u0438\u043C\u0435\u043D\u0438 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043E\u0442 2 \u0434\u043E 10 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/static/listmark.png b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/static/listmark.png
new file mode 100644
index 00000000..f8eb391b
Binary files /dev/null and b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/static/listmark.png differ
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..79546a1c
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/edit.html
@@ -0,0 +1,69 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/list.html
new file mode 100644
index 00000000..324fffad
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-demo/src/main/resources/templates/list.html
@@ -0,0 +1,74 @@
+
+
+
+
+ List of all persons
+
+
+
+
+
+
+Select language
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/.gitignore b/2024-01/spring-18-view/spring-mvc-view-exercise/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/pom.xml b/2024-01/spring-18-view/spring-mvc-view-exercise/pom.xml
new file mode 100644
index 00000000..eabab163
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-exercise
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..09283e91
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,14 @@
+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);
+ System.out.printf("Чтобы проверить себя открывай: %n%s%n%s%n",
+ "http://localhost:8080", "http://localhost:8080/edit?id=1");
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..5a345bbb
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,30 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ return null;
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/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/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/application.yml
new file mode 100644
index 00000000..c1f5d333
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..87d8c8f1
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/edit.html
@@ -0,0 +1,49 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/list.html
new file mode 100644
index 00000000..a5b52a8d
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-exercise/src/main/resources/templates/list.html
@@ -0,0 +1,49 @@
+
+
+
+
+ List of all persons
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/.gitignore b/2024-01/spring-18-view/spring-mvc-view-solution1/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/pom.xml b/2024-01/spring-18-view/spring-mvc-view-solution1/pom.xml
new file mode 100644
index 00000000..f95faf7e
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-solution1
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..c94edb10
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/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;
+
+//http://localhost:8080/edit?id=1
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..2953c703
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,33 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ Person person = repository.findById(id)
+ .orElseThrow(NotFoundException::new);
+ model.addAttribute("person", person);
+ return "edit";
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/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/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/application.yml
new file mode 100644
index 00000000..c1f5d333
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..7b3f5d6a
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/edit.html
@@ -0,0 +1,48 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/list.html
new file mode 100644
index 00000000..0d59a759
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution1/src/main/resources/templates/list.html
@@ -0,0 +1,50 @@
+
+
+
+
+ List of all persons
+
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/.gitignore b/2024-01/spring-18-view/spring-mvc-view-solution2/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/pom.xml b/2024-01/spring-18-view/spring-mvc-view-solution2/pom.xml
new file mode 100644
index 00000000..d30edbf2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-solution2
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..c94edb10
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/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;
+
+//http://localhost:8080/edit?id=1
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..ad22dbe8
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,32 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ Person person = repository.findById(id).orElseThrow(NotFoundException::new);
+ model.addAttribute("person", person);
+ return "edit";
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/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/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/application.yml
new file mode 100644
index 00000000..c1f5d333
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..ef643cff
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/edit.html
@@ -0,0 +1,48 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/list.html
new file mode 100644
index 00000000..a5b52a8d
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution2/src/main/resources/templates/list.html
@@ -0,0 +1,49 @@
+
+
+
+
+ List of all persons
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/.gitignore b/2024-01/spring-18-view/spring-mvc-view-solution3/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/pom.xml b/2024-01/spring-18-view/spring-mvc-view-solution3/pom.xml
new file mode 100644
index 00000000..2813038a
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-solution3
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..418ecb9b
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,14 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//http://localhost:8080
+//http://localhost:8080/edit?id=1
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..ad22dbe8
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,32 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ Person person = repository.findById(id).orElseThrow(NotFoundException::new);
+ model.addAttribute("person", person);
+ return "edit";
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/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/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/application.yml
new file mode 100644
index 00000000..c1f5d333
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/static/listmark.png b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/static/listmark.png
new file mode 100644
index 00000000..f8eb391b
Binary files /dev/null and b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/static/listmark.png differ
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..ef643cff
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/edit.html
@@ -0,0 +1,48 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/list.html
new file mode 100644
index 00000000..e7983e80
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution3/src/main/resources/templates/list.html
@@ -0,0 +1,49 @@
+
+
+
+
+ List of all persons
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/.gitignore b/2024-01/spring-18-view/spring-mvc-view-solution4/.gitignore
new file mode 100644
index 00000000..4ea52072
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/.gitignore
@@ -0,0 +1,24 @@
+target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/pom.xml b/2024-01/spring-18-view/spring-mvc-view-solution4/pom.xml
new file mode 100644
index 00000000..a9cc9993
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-mvc-view-solution4
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
+
+
+ 17
+ 17
+ 2.2.220
+ 2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+
+
+
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/Main.java b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/Main.java
new file mode 100644
index 00000000..418ecb9b
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/Main.java
@@ -0,0 +1,14 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//http://localhost:8080
+//http://localhost:8080/edit?id=1
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class);
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/NotFoundException.java b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/NotFoundException.java
new file mode 100644
index 00000000..41b48826
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/NotFoundException.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.controller;
+
+class NotFoundException extends RuntimeException{
+
+ NotFoundException() {
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/PersonController.java b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/PersonController.java
new file mode 100644
index 00000000..971bf323
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/controller/PersonController.java
@@ -0,0 +1,39 @@
+package ru.otus.spring.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import ru.otus.spring.domain.Person;
+import ru.otus.spring.repostory.PersonRepository;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class PersonController {
+
+ private final PersonRepository repository;
+
+ @GetMapping("/")
+ public String listPage(Model model) {
+ List persons = repository.findAll();
+ model.addAttribute("persons", persons);
+ return "list";
+ }
+
+ @GetMapping("/edit")
+ public String editPage(@RequestParam("id") long id, Model model) {
+ Person person = repository.findById(id).orElseThrow(NotFoundException::new);
+ model.addAttribute("person", person);
+ return "edit";
+ }
+
+ @PostMapping("/edit")
+ public String savePerson(Person person) {
+ repository.save(person);
+ return "redirect:/";
+ }
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/domain/Person.java b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/domain/Person.java
new file mode 100644
index 00000000..e40fd3f9
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/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 jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+ private String name;
+}
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/java/ru/otus/spring/repostory/PersonRepository.java
new file mode 100644
index 00000000..4fb88650
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/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/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/application.yml b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/application.yml
new file mode 100644
index 00000000..c1f5d333
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ sql:
+ init:
+ mode: always
+
+
+ jpa:
+ open-in-view: false
+ generate-ddl: false
+ hibernate:
+ ddl-auto: none
+
+ show-sql: true
+
+logging:
+ level:
+ ROOT: ERROR
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/data.sql b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/data.sql
new file mode 100644
index 00000000..7fa18c96
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/data.sql
@@ -0,0 +1,2 @@
+insert into person (id, name) values (1, 'Pushkin');
+insert into person (id, name) values (2, 'Lermontov');
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/schema.sql b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/schema.sql
new file mode 100644
index 00000000..f36202f2
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+create table person (
+ id integer generated by default as identity,
+ name varchar(255), primary key (id)
+);
\ No newline at end of file
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/edit.html b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/edit.html
new file mode 100644
index 00000000..4482d17a
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/edit.html
@@ -0,0 +1,48 @@
+
+
+
+
+ Edit person
+
+
+
+
+
+
+
+
+
diff --git a/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/list.html b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/list.html
new file mode 100644
index 00000000..9af2d61c
--- /dev/null
+++ b/2024-01/spring-18-view/spring-mvc-view-solution4/src/main/resources/templates/list.html
@@ -0,0 +1,49 @@
+
+
+
+
+ List of all persons
+
+
+
+Persons:
+
+
+
+
+ | ID |
+ Name |
+ Action |
+
+
+
+
+ | 1 |
+ John Doe |
+
+ Edit
+ |
+
+
+
+
+