Skip to content

Commit b376ca3

Browse files
committed
Part 22: Add dto folder with files
1 parent e1a6289 commit b376ca3

File tree

9 files changed

+218
-0
lines changed

9 files changed

+218
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package spring.oldboy.dto;
2+
3+
public record CompanyReadDto(Integer id,
4+
String name) {
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package spring.oldboy.dto;
2+
3+
import lombok.Value;
4+
5+
@Value
6+
public class LoginDto {
7+
String username;
8+
String password;
9+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package spring.oldboy.dto;
2+
/*
3+
Lesson 88 - На запрос с разбивкой по страницам нам
4+
нужен ответ, который будет отображаться пользователю
5+
*/
6+
import lombok.Value;
7+
import org.springframework.data.domain.Page;
8+
9+
import java.util.List;
10+
11+
@Value
12+
public class PagePaginationResponse <T> {
13+
/*
14+
Поле параметризованное Т, в нашем конкретном случае
15+
этот класс будет использоваться для класса user, хотя
16+
может использоваться и для company и т.д.
17+
*/
18+
List<T> content;
19+
/*
20+
Поле в котором будет храниться мета-информация:
21+
- page - номер страницы;
22+
- size - количество записей на одной странице;
23+
- totalElements - количество страниц записями из БД;
24+
см. сам класс ниже.
25+
*/
26+
Metadata metadata;
27+
28+
public static <T> PagePaginationResponse<T> of(Page<T> page) {
29+
Metadata metadata = new Metadata(page.getNumber(), page.getSize(), page.getTotalElements());
30+
return new PagePaginationResponse<>(page.getContent(), metadata);
31+
}
32+
33+
@Value
34+
public static class Metadata {
35+
int page;
36+
int size;
37+
long totalElements;
38+
}
39+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package spring.oldboy.dto;
2+
3+
import java.time.LocalDate;
4+
5+
public record PersonalInfo(String firstname,
6+
String lastname,
7+
LocalDate birthDate) {
8+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package spring.oldboy.dto;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
5+
public interface PersonalInfoTwo {
6+
7+
String getFirstname();
8+
9+
String getLastname();
10+
11+
String getBirthDate();
12+
13+
/*
14+
Особенность применения интерфейсов в проекциях сущностей в том, что
15+
мы можем запрашивать синтегрированные из полей данные с применением
16+
синтаксиса SpEL и аннотации @Value, которую мы используем для внедрения
17+
свойств.
18+
19+
В данном случае, terget - это текущая сущность PersonalInfoTwo и мы
20+
обращаемся к ней, хотя, тут, могли использоваться любые bean-ы из
21+
нашего приложения.
22+
23+
См. DOC/ArticleAboutProjection/SpringDataJPAProjections.txt
24+
*/
25+
@Value("#{target.firstname + ' ' + target.lastname}")
26+
String getFullName();
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package spring.oldboy.dto;
2+
3+
import spring.oldboy.database.entity.Role;
4+
5+
public record PersonalRole(String firstname,
6+
String lastname,
7+
Role role) {
8+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package spring.oldboy.dto;
2+
/*
3+
Lesson 89 - Применяем аннотации из пакета jakarta.validation к полям класса.
4+
*/
5+
import jakarta.validation.constraints.Email;
6+
import jakarta.validation.constraints.NotBlank;
7+
import jakarta.validation.constraints.Size;
8+
import lombok.Value;
9+
import lombok.experimental.FieldNameConstants;
10+
import org.springframework.format.annotation.DateTimeFormat;
11+
import org.springframework.web.multipart.MultipartFile;
12+
import spring.oldboy.database.entity.Role;
13+
import spring.oldboy.validation.UserInfo;
14+
import spring.oldboy.validation.group.CreateAction;
15+
16+
import java.time.LocalDate;
17+
18+
@Value
19+
/*
20+
Немного упростим себе жизнь на этапе тестирования. Данная аннотация создает внутренний тип,
21+
содержащий строковые константы, содержащие имя поля для каждого поля. В качестве альтернативы
22+
генерирует внутреннее перечисление со значениями перечисления, соответствующими каждому имени
23+
поля.
24+
*/
25+
@FieldNameConstants
26+
/*
27+
Применим нашу самописную аннотацию для валидации полей firstname
28+
и lastname, теперь аннотация @NotNull над этими полями не нужна.
29+
*/
30+
@UserInfo(groups = CreateAction.class)
31+
public class UserCreateEditDto {
32+
33+
/*
34+
Данная аннотация 'валидирует' - проверяет поле на
35+
правильность в ходе заполнения формы регистрации,
36+
а точнее в момент передачи данных в БД.
37+
38+
см. DOC/JakartaBeanValidation
39+
*/
40+
@Email
41+
String username;
42+
43+
/*
44+
Lesson 105: Добавляем поле пароля. Аннотация показывает, что элемент
45+
не должен быть нулевым и должен содержать хотя бы один символ без
46+
пробелов. В нашем случае с параметром уточнения - на этапе создания.
47+
Т.к. на изменение - UPDATE - пароля мы будем использовать другой
48+
функционал, изменяющий не всего USER-a, а только пароль.
49+
*/
50+
@NotBlank(groups = CreateAction.class)
51+
String rawPassword;
52+
53+
@DateTimeFormat(pattern = "yyyy-MM-dd")
54+
LocalDate birthDate;
55+
56+
/*
57+
Lesson 89: Проверяем чтобы сведения из поля формы не было пустым,
58+
а также длинна заполненной строки лежала в диапазоне от 3-х до 64
59+
символов. Хотя в данном случае лучше бы подошла аннотация - @NotEmpty,
60+
как и для поля ниже.
61+
62+
Lesson 90: Как только мы применим нашу кастомную аннотацию @UserInfo,
63+
текущая @NotNull уже не нужна.
64+
*/
65+
// @NotNull
66+
@Size(min = 3, max = 64)
67+
String firstname;
68+
69+
/*
70+
Lesson 90: Как только мы применим нашу кастомную аннотацию @UserInfo,
71+
текущая @NotNull уже не нужна.
72+
*/
73+
// @NotNull
74+
String lastname;
75+
76+
Role role;
77+
Integer companyId;
78+
/*
79+
Параметр нашей аватарки, имя поля в данном классе, должно совпадать
80+
с параметром name="image" в теге <input> наших форм регистрации
81+
(registration.html) и обновления-отображения (user.html) в
82+
resources/templates/user
83+
*/
84+
MultipartFile image;
85+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package spring.oldboy.dto;
2+
3+
import java.time.LocalDate;
4+
5+
/*
6+
Lesson 88:
7+
Каждый учитель городит свои заборы в уме студента! Если с фильтрацией User-ов
8+
было все более или менее понятно, то с постраничным выводом возникли вопросы,
9+
которые показали, что и с фильтрацией не все так гладко выглядит. Иногда
10+
название класса все поправляет. Например, текущее название этого record-a,
11+
намекает на то, что параметры оного - есть критерии фильтрации и как это не
12+
странно они же критерии поиска. Мы же ищем записи в БД удовлетворяющие неким
13+
условиям - "критериям". Отсюда название класса было бы уместнее задать как -
14+
UserSearchCriteria.
15+
*/
16+
public record UserFilterDto(String firstname,
17+
String lastname,
18+
LocalDate birthDate) {
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package spring.oldboy.dto;
2+
3+
import lombok.Value;
4+
import spring.oldboy.database.entity.Role;
5+
6+
import java.time.LocalDate;
7+
8+
@Value
9+
public class UserReadDto {
10+
Long id;
11+
String username;
12+
LocalDate birthDate;
13+
String firstname;
14+
String lastname;
15+
String image;
16+
Role role;
17+
CompanyReadDto company;
18+
}

0 commit comments

Comments
 (0)