2022-05 - 18

This commit is contained in:
ydvorzhetskiy
2022-07-29 22:53:47 +06:00
parent 317a180788
commit 0c5ac8a5f7
64 changed files with 2054 additions and 0 deletions
+24
View File
@@ -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/
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>spring-mvc-view-exercise</module>
<module>spring-mvc-view-demo</module>
<module>spring-mvc-view-solution1</module>
<module>spring-mvc-view-solution2</module>
<module>spring-mvc-view-solution3</module>
<module>spring-mvc-view-solution4</module>
</modules>
</project>
@@ -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/
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-demo</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<hibernate.validator.version>7.0.2.Final</hibernate.validator.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,27 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,35 @@
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();
resolver.setDefaultLocale(new Locale("en"));
resolver.setCookieName("locale");
return resolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
var localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,50 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.dto.PersonDto;
import ru.otus.spring.repostory.PersonRepository;
import javax.validation.Valid;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int id, Model model) {
Person person = repository.findById(id).orElseThrow(NotFoundException::new);
model.addAttribute("person", person);
return "edit";
}
@Validated
@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:/";
}
}
@@ -0,0 +1,42 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,51 @@
package ru.otus.spring.dto;
import ru.otus.spring.domain.Person;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class PersonDto {
private int 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 PersonDto() {
}
public PersonDto(String name) {
this.name = name;
}
public PersonDto(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person toDomainObject(){
return new Person(id, name);
}
public static PersonDto fromDomainObject(Person person) {
return new PersonDto(person.getId(), person.getName());
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
@@ -0,0 +1,3 @@
spring:
messages:
encoding: UTF-8
@@ -0,0 +1,10 @@
lang-switcher-header=Select language
en-lang-switch-button-caption=Language - EN
ru-lang-switch-button-caption=Language - RU
persons-table-header=Persons:
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
@@ -0,0 +1,10 @@
lang-switcher-header=Select language
en-lang-switch-button-caption=Language - EN
ru-lang-switch-button-caption=Language - RU
persons-table-header=Persons:
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
@@ -0,0 +1,10 @@
lang-switcher-header=Выбор языка
en-lang-switch-button-caption=Язык - EN
ru-lang-switch-button-caption=Язык - RU
persons-table-header=Пёрсоны:
edit-button-caption=Изменить
person-form-header=Информация о пёрсоне:
save-button-caption=Сохранить
cancel-button-caption=Отмена
name-field-should-not-be-blank=Имя не должно быть пустым
name-field-should-has-expected-size=Длина имени должна быть от 2 до 10 символов
Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
h3 {
background-image: url("../static/listmark.png");
background-repeat: no-repeat;
padding: 2px;
padding-left: 30px;
}
.errors {
color: red;
}
</style>
<style type="text/css" th:inline="text">
[[h3]] {
background-image: url([[@{/listmark.png}]]);
background-repeat: no-repeat;
padding: 2px;
padding-left: 30px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html" th:action="@{/edit(id=${person.id})}" th:method="post" th:object="${person}">
<h3 th:text = "#{person-form-header}">Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" th:value="*{id}" value="1"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" th:value="*{name}" value="John Doe"/>
<div class="errors" th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Wrong person name error</div>
</div>
<div class="row">
<button type="submit" th:text="#{save-button-caption}">Save</button>
<a href="list.html" th:href="@{/}"><button type="button" th:text="#{cancel-button-caption}">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
h3 {
background-image: url("../static/listmark.png");
background-repeat: no-repeat;
padding: 2px;
padding-left: 30px;
}
</style>
<style type="text/css" th:inline="text">
[[h3]] {
background-image: url([[@{/listmark.png}]]);
background-repeat: no-repeat;
padding: 2px;
padding-left: 30px;
}
</style>
</head>
<body>
<h3 th:text="#{lang-switcher-header}">Select language</h3>
<div>
<div><a href="#" th:href="@{/(lang=en)}" th:text="#{en-lang-switch-button-caption}">Language - EN</a></div>
<div><a href="#" th:href="@{/(lang=ru)}" th:text="#{ru-lang-switch-button-caption}">Language - RU</a></div>
</div>
<h3 th:text="#{persons-table-header}">Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="person : ${persons}">
<td th:text="${person.id}">1</td>
<td th:text="${person.name}">John Doe</td>
<td>
<a th:href="@{/edit(id=${person.id})}" href="edit.html" th:text="#{edit-button-caption}">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@@ -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/
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-exercise</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,28 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
//Чтобы не усложнять пример, делать так нельзя :)
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,33 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int id, Model model) {
return null;
}
}
@@ -0,0 +1,37 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html">
<h3>Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" value="1"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" value="John Doe"/>
</div>
<div class="row">
<button type="submit">Save</button>
<a href="list.html"><button type="button">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
</style>
</head>
<body>
<h3>Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John Doe</td>
<td>
<a href="edit.html">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@@ -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/
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-solution1</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,29 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
//http://localhost:8080/edit?id=1
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
//Чтобы не усложнять пример, делать так нельзя :)
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,35 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int id, Model model) {
Person person = repository.findById(id).orElseThrow(NotFoundException::new);
model.addAttribute("person", person);
return "edit";
}
}
@@ -0,0 +1,37 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html">
<h3>Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" value="1" th:value="${person.id}"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" value="John Doe" th:value="${person.name}"/>
</div>
<div class="row">
<button type="submit">Save</button>
<a href="list.html"><button type="button">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
</style>
</head>
<body>
<h3>Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John Doe</td>
<td>
<a href="edit.html">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@@ -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/
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-solution2</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,29 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
//http://localhost:8080/edit?id=1
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
//Чтобы не усложнять пример, делать так нельзя :)
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,35 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int id, Model model) {
Person person = repository.findById(id).orElseThrow(NotFoundException::new);
model.addAttribute("person", person);
return "edit";
}
}
@@ -0,0 +1,37 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html" th:object="${person}">
<h3>Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" value="1" th:value="*{id}"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" value="John Doe" th:value="*{name}"/>
</div>
<div class="row">
<button type="submit">Save</button>
<a href="list.html"><button type="button">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
</style>
</head>
<body>
<h3>Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>John Doe</td>
<td>
<a href="edit.html">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@@ -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/
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-solution3</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,30 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
//http://localhost:8080
//http://localhost:8080/edit?id=1
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
//Чтобы не усложнять пример, делать так нельзя :)
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,35 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int id, Model model) {
Person person = repository.findById(id).orElseThrow(NotFoundException::new);
model.addAttribute("person", person);
return "edit";
}
}
@@ -0,0 +1,37 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html" th:object="${person}">
<h3>Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" value="1" th:value="*{id}"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" value="John Doe" th:value="*{name}"/>
</div>
<div class="row">
<button type="submit">Save</button>
<a href="list.html"><button type="button">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
</style>
</head>
<body>
<h3>Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="person : ${persons}">
<td th:text="${person.id}">1</td>
<td th:text="${person.name}">John Doe</td>
<td>
<a href="edit.html">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@@ -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/
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>spring-mvc-view-solution4</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,30 @@
package ru.otus.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import javax.annotation.PostConstruct;
//http://localhost:8080
//http://localhost:8080/edit?id=1
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
//Чтобы не усложнять пример, делать так нельзя :)
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PersonRepository repository;
@PostConstruct
public void init() {
repository.save(new Person("Pushkin"));
repository.save(new Person("Lermontov"));
}
}
@@ -0,0 +1,7 @@
package ru.otus.spring.controller;
class NotFoundException extends RuntimeException{
NotFoundException() {
}
}
@@ -0,0 +1,41 @@
package ru.otus.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.domain.Person;
import ru.otus.spring.repostory.PersonRepository;
import java.util.List;
@Controller
public class PersonController {
private final PersonRepository repository;
@Autowired
public PersonController(PersonRepository repository) {
this.repository = repository;
}
@GetMapping("/")
public String listPage(Model model) {
List<Person> persons = repository.findAll();
model.addAttribute("persons", persons);
return "list";
}
@GetMapping("/edit")
public String editPage(@RequestParam("id") int 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:/";
}
}
@@ -0,0 +1,37 @@
package ru.otus.spring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -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<Person, Integer> {
List<Person> findAll();
}
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit person</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<!-- Person edition -->
<form id="edit-form" action="edit.html" th:method="post" th:action="@{/edit(id=${person.id})}" th:object="${person}">
<h3>Person Info:</h3>
<div class="row">
<label for="id-input">ID:</label>
<input id="id-input" type="text" readonly="readonly" value="1" th:value="*{id}"/>
</div>
<div class="row">
<label for="person-name-input">Name:</label>
<input id="person-name-input" name="name" type="text" value="John Doe" th:value="*{name}"/>
</div>
<div class="row">
<button type="submit">Save</button>
<a href="list.html" th:href="@{/}"><button type="button">Cancel</button></a>
</div>
</form>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>List of all persons</title>
<style type="text/css">
body {
padding: 50px;
}
.persons {
border: 1px solid steelblue;
width: 300px;
border-collapse: collapse;
}
.persons tr td, th {
padding: 5px;
border: 1px solid steelblue;
}
.persons td:last-child, td:first-child {
width: 50px;
}
</style>
</head>
<body>
<h3>Persons:</h3>
<table class="persons">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="person : ${persons}">
<td th:text="${person.id}">1</td>
<td th:text="${person.name}">John Doe</td>
<td>
<a href="edit.html" th:href="@{/edit(id=${person.id})}">Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>