From 979be859a903d10ca431f04d4fff8533d3e425b0 Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2022年12月31日 03:37:28 +0300 Subject: [PATCH 01/14] 1_01_user_with_lombok --- 1_01_user_with_lombok.patch | 69 +++++++++++++++++++ pom.xml | 8 +++ .../java/ru/javaops/bootjava/model/Role.java | 6 ++ .../java/ru/javaops/bootjava/model/User.java | 23 +++++++ 4 files changed, 106 insertions(+) create mode 100644 1_01_user_with_lombok.patch create mode 100644 src/main/java/ru/javaops/bootjava/model/Role.java create mode 100644 src/main/java/ru/javaops/bootjava/model/User.java diff --git a/1_01_user_with_lombok.patch b/1_01_user_with_lombok.patch new file mode 100644 index 0000000..3ffcec1 --- /dev/null +++ b/1_01_user_with_lombok.patch @@ -0,0 +1,69 @@ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (revision 35a21d499357b464ebb5b571cb97ac0bc5e57f01) ++++ pom.xml (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) +@@ -53,6 +53,14 @@ + + org.springframework.boot + spring-boot-maven-plugin ++ ++ ++ ++ org.projectlombok ++ lombok ++ ++ ++ + + + +Index: src/main/java/ru/javaops/bootjava/model/Role.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/bootjava/model/Role.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) ++++ src/main/java/ru/javaops/bootjava/model/Role.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) +@@ -0,0 +1,6 @@ ++package ru.javaops.bootjava.model; ++ ++public enum Role { ++ ROLE_USER, ++ ROLE_ADMIN ++} +\ No newline at end of file +Index: src/main/java/ru/javaops/bootjava/model/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/bootjava/model/User.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) ++++ src/main/java/ru/javaops/bootjava/model/User.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) +@@ -0,0 +1,23 @@ ++package ru.javaops.bootjava.model; ++ ++import lombok.AllArgsConstructor; ++import lombok.Data; ++import lombok.NoArgsConstructor; ++ ++import java.util.Set; ++ ++@Data ++@NoArgsConstructor ++@AllArgsConstructor ++public class User { ++ ++ private String email; ++ ++ private String firstName; ++ ++ private String lastName; ++ ++ private String password; ++ ++ private Set roles; ++} +\ No newline at end of file diff --git a/pom.xml b/pom.xml index ca66a72..5be7a42 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,14 @@ org.springframework.boot spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + diff --git a/src/main/java/ru/javaops/bootjava/model/Role.java b/src/main/java/ru/javaops/bootjava/model/Role.java new file mode 100644 index 0000000..432dde8 --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/model/Role.java @@ -0,0 +1,6 @@ +package ru.javaops.bootjava.model; + +public enum Role { + ROLE_USER, + ROLE_ADMIN +} \ No newline at end of file diff --git a/src/main/java/ru/javaops/bootjava/model/User.java b/src/main/java/ru/javaops/bootjava/model/User.java new file mode 100644 index 0000000..b475761 --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/model/User.java @@ -0,0 +1,23 @@ +package ru.javaops.bootjava.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class User { + + private String email; + + private String firstName; + + private String lastName; + + private String password; + + private Set roles; +} \ No newline at end of file From 65bbb85cb9750b6cd1d13db0f56ffdf7651dc120 Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月12日 15:50:53 +0300 Subject: [PATCH 02/14] 2_01_data_jpa --- pom.xml | 4 +++ .../bootjava/RestaurantVotingApplication.java | 17 +++++++++- .../java/ru/javaops/bootjava/model/User.java | 33 +++++++++++++++---- .../bootjava/repository/UserRepository.java | 7 ++++ src/main/resources/application.properties | 9 +++++ 5 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/main/java/ru/javaops/bootjava/repository/UserRepository.java diff --git a/pom.xml b/pom.xml index 5be7a42..bf8aa32 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + com.h2database diff --git a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java index 3326420..61d8ff8 100644 --- a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java +++ b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java @@ -1,14 +1,29 @@ package ru.javaops.bootjava; import lombok.AllArgsConstructor; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.javaops.bootjava.model.Role; +import ru.javaops.bootjava.model.User; +import ru.javaops.bootjava.repository.UserRepository; + +import java.util.Set; @SpringBootApplication @AllArgsConstructor -public class RestaurantVotingApplication { +public class RestaurantVotingApplication implements ApplicationRunner { + private final UserRepository userRepository; public static void main(String[] args) { SpringApplication.run(RestaurantVotingApplication.class, args); } + + @Override + public void run(ApplicationArguments args) { + userRepository.save(new User("user@gmail.com", "User_First", "User_Last", "password", Set.of(Role.ROLE_USER))); + userRepository.save(new User("admin@javaops.ru", "Admin_First", "Admin_Last", "admin", Set.of(Role.ROLE_USER, Role.ROLE_ADMIN))); + System.out.println(userRepository.findAll()); + } } diff --git a/src/main/java/ru/javaops/bootjava/model/User.java b/src/main/java/ru/javaops/bootjava/model/User.java index b475761..284f632 100644 --- a/src/main/java/ru/javaops/bootjava/model/User.java +++ b/src/main/java/ru/javaops/bootjava/model/User.java @@ -1,23 +1,44 @@ package ru.javaops.bootjava.model; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; +import org.springframework.data.jpa.domain.AbstractPersistable; +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Size; import java.util.Set; -@Data -@NoArgsConstructor +@Entity +@Table(name = "users") +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor -public class User { +@ToString(callSuper = true, exclude = {"password"}) +public class User extends AbstractPersistable { + @Column(name = "email", nullable = false, unique = true) + @Email + @NotEmpty + @Size(max = 128) private String email; + @Column(name = "first_name") + @Size(max = 128) private String firstName; + @Column(name = "last_name") + @Size(max = 128) private String lastName; + @Column(name = "password") + @Size(max = 256) private String password; + @Enumerated(EnumType.STRING) + @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "role"}, name = "user_roles_unique")}) + @Column(name = "role") + @ElementCollection(fetch = FetchType.EAGER) private Set roles; } \ No newline at end of file diff --git a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java new file mode 100644 index 0000000..590c614 --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java @@ -0,0 +1,7 @@ +package ru.javaops.bootjava.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.javaops.bootjava.model.User; + +public interface UserRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e69de29..3492ea9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -0,0 +1,9 @@ +# https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html +# JPA +spring.jpa.show-sql=true +spring.jpa.open-in-view=false +# http://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#configurations +spring.jpa.properties.hibernate.default_batch_fetch_size=20 +spring.jpa.properties.hibernate.format_sql=true +# https://stackoverflow.com/questions/21257819/what-is-the-difference-between-hibernate-jdbc-fetch-size-and-hibernate-jdbc-batc +spring.jpa.properties.hibernate.jdbc.batch_size=20 From f9a7cfce36fcb78cedf099b224f4af4e36dd982a Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月13日 02:38:37 +0300 Subject: [PATCH 03/14] 2_02_h2_init.patch --- 1_01_user_with_lombok.patch | 69 ------------------- pom.xml | 1 - .../bootjava/RestaurantVotingApplication.java | 6 -- .../ru/javaops/bootjava/config/AppConfig.java | 26 +++++++ src/main/resources/application.properties | 9 --- src/main/resources/application.yaml | 30 ++++++++ src/main/resources/data.sql | 8 +++ 7 files changed, 64 insertions(+), 85 deletions(-) delete mode 100644 1_01_user_with_lombok.patch create mode 100644 src/main/java/ru/javaops/bootjava/config/AppConfig.java delete mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.yaml create mode 100644 src/main/resources/data.sql diff --git a/1_01_user_with_lombok.patch b/1_01_user_with_lombok.patch deleted file mode 100644 index 3ffcec1..0000000 --- a/1_01_user_with_lombok.patch +++ /dev/null @@ -1,69 +0,0 @@ -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (revision 35a21d499357b464ebb5b571cb97ac0bc5e57f01) -+++ pom.xml (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) -@@ -53,6 +53,14 @@ - - org.springframework.boot - spring-boot-maven-plugin -+ -+ -+ -+ org.projectlombok -+ lombok -+ -+ -+ - - - -Index: src/main/java/ru/javaops/bootjava/model/Role.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/bootjava/model/Role.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) -+++ src/main/java/ru/javaops/bootjava/model/Role.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) -@@ -0,0 +1,6 @@ -+package ru.javaops.bootjava.model; -+ -+public enum Role { -+ ROLE_USER, -+ ROLE_ADMIN -+} -\ No newline at end of file -Index: src/main/java/ru/javaops/bootjava/model/User.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/bootjava/model/User.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) -+++ src/main/java/ru/javaops/bootjava/model/User.java (revision 9838d0cefa7b1babfb52ff1702bcb490e934761c) -@@ -0,0 +1,23 @@ -+package ru.javaops.bootjava.model; -+ -+import lombok.AllArgsConstructor; -+import lombok.Data; -+import lombok.NoArgsConstructor; -+ -+import java.util.Set; -+ -+@Data -+@NoArgsConstructor -+@AllArgsConstructor -+public class User { -+ -+ private String email; -+ -+ private String firstName; -+ -+ private String lastName; -+ -+ private String password; -+ -+ private Set roles; -+} -\ No newline at end of file diff --git a/pom.xml b/pom.xml index bf8aa32..0fe4458 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,6 @@ com.h2database h2 - runtime org.projectlombok diff --git a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java index 61d8ff8..d3b1792 100644 --- a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java +++ b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java @@ -5,12 +5,8 @@ import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import ru.javaops.bootjava.model.Role; -import ru.javaops.bootjava.model.User; import ru.javaops.bootjava.repository.UserRepository; -import java.util.Set; - @SpringBootApplication @AllArgsConstructor public class RestaurantVotingApplication implements ApplicationRunner { @@ -22,8 +18,6 @@ public static void main(String[] args) { @Override public void run(ApplicationArguments args) { - userRepository.save(new User("user@gmail.com", "User_First", "User_Last", "password", Set.of(Role.ROLE_USER))); - userRepository.save(new User("admin@javaops.ru", "Admin_First", "Admin_Last", "admin", Set.of(Role.ROLE_USER, Role.ROLE_ADMIN))); System.out.println(userRepository.findAll()); } } diff --git a/src/main/java/ru/javaops/bootjava/config/AppConfig.java b/src/main/java/ru/javaops/bootjava/config/AppConfig.java new file mode 100644 index 0000000..19dbc45 --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/config/AppConfig.java @@ -0,0 +1,26 @@ +package ru.javaops.bootjava.config; + +import lombok.extern.slf4j.Slf4j; +import org.h2.tools.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.sql.SQLException; + +@Configuration +@Slf4j +public class AppConfig { + +/* + @Bean(initMethod = "start", destroyMethod = "stop") + public Server h2WebServer() throws SQLException { + return Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082"); + } +*/ + + @Bean(initMethod = "start", destroyMethod = "stop") + public Server h2Server() throws SQLException { + log.info("Start H2 TCP server"); + return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092"); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 3492ea9..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,9 +0,0 @@ -# https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html -# JPA -spring.jpa.show-sql=true -spring.jpa.open-in-view=false -# http://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#configurations -spring.jpa.properties.hibernate.default_batch_fetch_size=20 -spring.jpa.properties.hibernate.format_sql=true -# https://stackoverflow.com/questions/21257819/what-is-the-difference-between-hibernate-jdbc-fetch-size-and-hibernate-jdbc-batc -spring.jpa.properties.hibernate.jdbc.batch_size=20 diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..056db27 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,30 @@ +# https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html +spring: + jpa: + show-sql: true + open-in-view: false + hibernate: + ddl-auto: create-drop + properties: + # http://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#configurations + hibernate: + format_sql: true + default_batch_fetch_size: 20 + # https://stackoverflow.com/questions/21257819/what-is-the-difference-between-hibernate-jdbc-fetch-size-and-hibernate-jdbc-batc + jdbc.batch_size: 20 + id.new_generator_mappings: false + datasource: + # ImMemory + url: jdbc:h2:mem:voting + # tcp: jdbc:h2:tcp://localhost:9092/mem:voting + # Absolute path + # url: jdbc:h2:C:/projects/bootjava/restorant-voting/db/voting + # tcp: jdbc:h2:tcp://localhost:9092/C:/projects/bootjava/restorant-voting/db/voting + # Relative path form current dir + # url: jdbc:h2:./db/voting + # Relative path from home + # url: jdbc:h2:~/voting + # tcp: jdbc:h2:tcp://localhost:9092/~/voting + username: sa + password: sa + h2.console.enabled: true \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..0fe391f --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,8 @@ +INSERT INTO USERS (EMAIL, FIRST_NAME, LAST_NAME, PASSWORD) +VALUES ('user@gmail.com', 'User_First', 'User_Last', 'password'), + ('admin@javaops.ru', 'Admin_First', 'Admin_Last', 'admin'); + +INSERT INTO USER_ROLE (ROLE, USER_ID) +VALUES ('ROLE_USER', 1), + ('ROLE_ADMIN', 2), + ('ROLE_USER', 2); \ No newline at end of file From 7d90ce7479413ed590600b8c364b029a6452db70 Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月14日 03:10:03 +0300 Subject: [PATCH 04/14] 2_03_model_query --- .../bootjava/RestaurantVotingApplication.java | 4 +- .../ru/javaops/bootjava/model/BaseEntity.java | 52 +++++++++++++++++++ .../java/ru/javaops/bootjava/model/User.java | 3 +- .../bootjava/repository/UserRepository.java | 13 +++++ src/main/resources/application.yaml | 1 - 5 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/main/java/ru/javaops/bootjava/model/BaseEntity.java diff --git a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java index d3b1792..14a0d76 100644 --- a/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java +++ b/src/main/java/ru/javaops/bootjava/RestaurantVotingApplication.java @@ -18,6 +18,8 @@ public static void main(String[] args) { @Override public void run(ApplicationArguments args) { - System.out.println(userRepository.findAll()); + System.out.println(userRepository.findByLastNameContainingIgnoreCase("last")); + System.out.println(); + System.out.println(userRepository.findByPasswordContaining("ass")); } } diff --git a/src/main/java/ru/javaops/bootjava/model/BaseEntity.java b/src/main/java/ru/javaops/bootjava/model/BaseEntity.java new file mode 100644 index 0000000..4a697e5 --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/model/BaseEntity.java @@ -0,0 +1,52 @@ +package ru.javaops.bootjava.model; + +import lombok.*; +import org.springframework.data.domain.Persistable; +import org.springframework.data.util.ProxyUtils; +import org.springframework.util.Assert; + +import javax.persistence.*; + +@MappedSuperclass +// https://stackoverflow.com/a/6084701/548473 +@Access(AccessType.FIELD) +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@ToString +public abstract class BaseEntity implements Persistable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + protected Integer id; + + // doesn't work for hibernate lazy proxy + public int id() { + Assert.notNull(id, "Entity must have id"); + return id; + } + + @Override + public boolean isNew() { + return id == null; + } + + // https://stackoverflow.com/questions/1638723 + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || !getClass().equals(ProxyUtils.getUserClass(o))) { + return false; + } + BaseEntity that = (BaseEntity) o; + return id != null && id.equals(that.id); + } + + @Override + public int hashCode() { + return id == null ? 0 : id; + } +} \ No newline at end of file diff --git a/src/main/java/ru/javaops/bootjava/model/User.java b/src/main/java/ru/javaops/bootjava/model/User.java index 284f632..575aaff 100644 --- a/src/main/java/ru/javaops/bootjava/model/User.java +++ b/src/main/java/ru/javaops/bootjava/model/User.java @@ -1,7 +1,6 @@ package ru.javaops.bootjava.model; import lombok.*; -import org.springframework.data.jpa.domain.AbstractPersistable; import javax.persistence.*; import javax.validation.constraints.Email; @@ -16,7 +15,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @ToString(callSuper = true, exclude = {"password"}) -public class User extends AbstractPersistable { +public class User extends BaseEntity { @Column(name = "email", nullable = false, unique = true) @Email diff --git a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java index 590c614..3618bf8 100644 --- a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java +++ b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java @@ -1,7 +1,20 @@ package ru.javaops.bootjava.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; import ru.javaops.bootjava.model.User; +import java.util.List; +import java.util.Optional; + +@Transactional(readOnly = true) public interface UserRepository extends JpaRepository { + + @Query("SELECT u FROM User u WHERE u.email = LOWER(:email)") + Optional findByEmailIgnoreCase(String email); + + List findByLastNameContainingIgnoreCase(String lastName); + + List findByPasswordContaining(String password); } \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 056db27..f13208c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -12,7 +12,6 @@ spring: default_batch_fetch_size: 20 # https://stackoverflow.com/questions/21257819/what-is-the-difference-between-hibernate-jdbc-fetch-size-and-hibernate-jdbc-batc jdbc.batch_size: 20 - id.new_generator_mappings: false datasource: # ImMemory url: jdbc:h2:mem:voting From 10f5877f29f80f5226faccd35b1ea6e27de43e4c Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月15日 21:41:12 +0300 Subject: [PATCH 05/14] 3_01_jpa_data_rest --- pom.xml | 12 +++++++++++- .../javaops/bootjava/repository/UserRepository.java | 4 ++++ src/main/resources/application.yaml | 8 +++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0fe4458..5aabae1 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,17 @@ org.springframework.boot spring-boot-starter-validation - + + org.springframework.boot + spring-boot-starter-data-rest + + com.h2database h2 diff --git a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java index 3618bf8..6b2ba24 100644 --- a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java +++ b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java @@ -2,6 +2,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.transaction.annotation.Transactional; import ru.javaops.bootjava.model.User; @@ -11,10 +12,13 @@ @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { + @RestResource(rel = "by-email", path = "by-email") @Query("SELECT u FROM User u WHERE u.email = LOWER(:email)") Optional findByEmailIgnoreCase(String email); + @RestResource(rel = "by-lastname", path = "by-lastname") List findByLastNameContainingIgnoreCase(String lastName); + @RestResource(rel = "by-password", path = "by-password", exported = false) List findByPasswordContaining(String password); } \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f13208c..0795ac0 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -26,4 +26,10 @@ spring: # tcp: jdbc:h2:tcp://localhost:9092/~/voting username: sa password: sa - h2.console.enabled: true \ No newline at end of file + h2.console.enabled: true + + data.rest: + # https://docs.spring.io/spring-data/rest/docs/current/reference/html/#getting-started.basic-settings + basePath: /api + returnBodyOnCreate: true + From a8537b2640ea502677ed82437a821868fa7a36bb Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月15日 23:37:17 +0300 Subject: [PATCH 06/14] 3_02_jackson --- src/main/java/ru/javaops/bootjava/model/BaseEntity.java | 2 ++ src/main/resources/application.yaml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/main/java/ru/javaops/bootjava/model/BaseEntity.java b/src/main/java/ru/javaops/bootjava/model/BaseEntity.java index 4a697e5..72ed0fc 100644 --- a/src/main/java/ru/javaops/bootjava/model/BaseEntity.java +++ b/src/main/java/ru/javaops/bootjava/model/BaseEntity.java @@ -1,5 +1,6 @@ package ru.javaops.bootjava.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.*; import org.springframework.data.domain.Persistable; import org.springframework.data.util.ProxyUtils; @@ -27,6 +28,7 @@ public int id() { return id; } + @JsonIgnore @Override public boolean isNew() { return id == null; diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 0795ac0..f6bbc73 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -33,3 +33,10 @@ spring: basePath: /api returnBodyOnCreate: true +# Jackson Serialization Issue Resolver +# jackson: +# visibility.field: any +# visibility.getter: none +# visibility.setter: none +# visibility.is-getter: none + From c16c7ffe854f41338135370197ec46d6f0788abb Mon Sep 17 00:00:00 2001 From: ParshinSergey Date: 2023年1月16日 04:03:25 +0300 Subject: [PATCH 07/14] 4_01_add_security --- pom.xml | 5 +++++ src/main/resources/application.yaml | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/pom.xml b/pom.xml index 5aabae1..04dd5c3 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,11 @@ org.springframework.boot spring-boot-starter-data-rest + + org.springframework.boot + spring-boot-starter-security + + ++ ++ ++ ++ org.springdoc ++ springdoc-openapi-ui ++ ${springdoc.version} ++ ++ ++ org.springdoc ++ springdoc-openapi-data-rest ++ ${springdoc.version} ++ ++ ++ org.springdoc ++ springdoc-openapi-security ++ ${springdoc.version} ++ + + com.h2database + h2 +@@ -58,7 +76,7 @@ + true + + +- ++ + + org.springframework.boot + spring-boot-starter-test +Index: src/main/java/ru/javaops/bootjava/web/AccountController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/main/java/ru/javaops/bootjava/web/AccountController.java b/src/main/java/ru/javaops/bootjava/web/AccountController.java +--- a/src/main/java/ru/javaops/bootjava/web/AccountController.java (revision 24f7e7fc8451a22eebdef8431f271b6b7fb52941) ++++ b/src/main/java/ru/javaops/bootjava/web/AccountController.java (date 1616948395033) +@@ -1,5 +1,6 @@ + package ru.javaops.bootjava.web; + ++import io.swagger.v3.oas.annotations.tags.Tag; + import lombok.AllArgsConstructor; + import lombok.extern.slf4j.Slf4j; + import org.springframework.data.rest.webmvc.RepositoryLinksResource; +@@ -38,6 +39,7 @@ + @RequestMapping("/api/account") + @AllArgsConstructor + @Slf4j ++@Tag(name = "Account Controller") + public class AccountController implements RepresentationModelProcessor { + @SuppressWarnings("unchecked") + private static final RepresentationModelAssemblerSupport> ASSEMBLER = diff --git a/pom.xml b/pom.xml index 04dd5c3..43ff567 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ 15 + 1.5.6 @@ -48,6 +49,23 @@ runtime --> + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + org.springdoc + springdoc-openapi-data-rest + ${springdoc.version} + + + org.springdoc + springdoc-openapi-security + ${springdoc.version} + com.h2database h2 @@ -58,7 +76,7 @@ true - + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/ru/javaops/bootjava/config/OpenApiConfig.java b/src/main/java/ru/javaops/bootjava/config/OpenApiConfig.java new file mode 100644 index 0000000..4f6293d --- /dev/null +++ b/src/main/java/ru/javaops/bootjava/config/OpenApiConfig.java @@ -0,0 +1,39 @@ +package ru.javaops.bootjava.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +//https://sabljakovich.medium.com/adding-basic-auth-authorization-option-to-openapi-swagger-documentation-java-spring-95abbede27e9 +@SecurityScheme( + name = "basicAuth", + type = SecuritySchemeType.HTTP, + scheme = "basic" +) +@OpenAPIDefinition( + info = @Info( + title = "REST API documentation", + version = "1.0", + description = "Приложение по курсу BootJava", + contact = @Contact(url = "https://javaops.ru/#contacts", name = "Grigory Kislin", email = "admin@javaops.ru") + ), + security = @SecurityRequirement(name = "basicAuth") +) +public class OpenApiConfig { + + @Bean + public GroupedOpenApi api() { + return GroupedOpenApi.builder() + .group("REST API") + .pathsToMatch("/api/**") + .pathsToExclude("/api/profile/**") + .build(); + } +} diff --git a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java index 6ddc674..b74ed85 100644 --- a/src/main/java/ru/javaops/bootjava/repository/UserRepository.java +++ b/src/main/java/ru/javaops/bootjava/repository/UserRepository.java @@ -1,5 +1,6 @@ package ru.javaops.bootjava.repository; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -12,6 +13,7 @@ import java.util.Optional; @Transactional(readOnly = true) +@Tag(name = "User Controller") public interface UserRepository extends JpaRepository { @RestResource(rel = "by-email", path = "by-email") diff --git a/src/main/java/ru/javaops/bootjava/web/AccountController.java b/src/main/java/ru/javaops/bootjava/web/AccountController.java index ca19178..183644a 100644 --- a/src/main/java/ru/javaops/bootjava/web/AccountController.java +++ b/src/main/java/ru/javaops/bootjava/web/AccountController.java @@ -1,5 +1,6 @@ package ru.javaops.bootjava.web; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; @@ -40,6 +41,7 @@ @RequestMapping("/api/account") @AllArgsConstructor @Slf4j +@Tag(name = "Account Controller") public class AccountController implements RepresentationModelProcessor { @SuppressWarnings("unchecked")

AltStyle によって変換されたページ (->オリジナル) /