├── .gitignore
├── CODEOWNERS
├── README.md
├── media
├── Programowanie-w-javie-solidne-fundamenty.jpg
└── Tworzenie_projektu.PNG
├── module_1
├── README.md
└── resolutions
│ ├── 1.3.md
│ ├── 1.4.md
│ ├── 1.5.md
│ └── 1.6.md
├── module_2
├── README.md
└── resolutions
│ ├── 2.1.md
│ ├── 2.2.md
│ ├── 2.3.md
│ ├── 2.4.md
│ ├── 2.5.md
│ ├── 2.6.md
│ ├── 2.7.md
│ └── 2.8.md
├── module_3
├── README.md
└── resolutions
│ ├── 3.1.md
│ ├── 3.2.md
│ ├── 3.3.md
│ ├── 3.4.md
│ ├── 3.5.md
│ ├── 3.6.md
│ ├── 3.7.md
│ ├── 3.8.md
│ └── 3.9.md
├── module_4
└── README.md
└── projects
├── honestit-2020-10-11
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── pl
│ │ │ └── sda
│ │ │ └── projects
│ │ │ └── adverts
│ │ │ ├── AdvertsApplication.java
│ │ │ ├── config
│ │ │ ├── SecurityConfig.java
│ │ │ └── StartupDataLoader.java
│ │ │ ├── controller
│ │ │ ├── HomePageController.java
│ │ │ └── RegistrationController.java
│ │ │ └── model
│ │ │ ├── domain
│ │ │ ├── Advert.java
│ │ │ └── User.java
│ │ │ └── repository
│ │ │ ├── AdvertRepository.java
│ │ │ └── UserRepository.java
│ └── resources
│ │ ├── application.properties
│ │ └── templates
│ │ ├── home.html
│ │ ├── index.html
│ │ └── registration
│ │ ├── registration-form.html
│ │ └── registration-summary.html
│ └── test
│ └── java
│ └── pl
│ └── sda
│ └── projects
│ └── adverts
│ └── AdvertsApplicationTests.java
├── honestit
└── demo
│ ├── .gitignore
│ ├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── pl
│ │ │ └── honestit
│ │ │ └── spring
│ │ │ └── demo
│ │ │ ├── DemoApplication.java
│ │ │ ├── config
│ │ │ └── SecurityConfiguration.java
│ │ │ ├── controllers
│ │ │ ├── AdvertController.java
│ │ │ ├── HomePageController.java
│ │ │ ├── LoginController.java
│ │ │ ├── RegistrationController.java
│ │ │ └── UserAdvertsController.java
│ │ │ └── model
│ │ │ ├── domain
│ │ │ ├── Advert.java
│ │ │ └── User.java
│ │ │ └── repositories
│ │ │ ├── AdvertRepository.java
│ │ │ └── UserRepository.java
│ ├── resources
│ │ └── application.properties
│ └── webapp
│ │ └── WEB-INF
│ │ └── views
│ │ ├── edit-advert-page.jsp
│ │ ├── fragments
│ │ └── main-menu.jsp
│ │ ├── home-page.jsp
│ │ ├── login-page.jsp
│ │ ├── registration-form.jsp
│ │ └── user-adverts-page.jsp
│ └── test
│ └── java
│ └── pl
│ └── honestit
│ └── spring
│ └── demo
│ └── DemoApplicationTests.java
└── mygithub
├── .gitignore
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── pl
│ │ └── sda
│ │ └── projects
│ │ └── adverts
│ │ └── AdvertsApplication.java
└── resources
│ └── application.properties
└── test
└── java
└── pl
└── sda
└── projects
└── adverts
└── AdvertsApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | # IntelliJ
26 | *.iml
27 | .idea/**
28 | **/.idea/**
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @honestit
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spring Intro
2 |
3 | Repozytorium warsztatowe z zadaniami wprowadzającymi do świata Springa (dla Spring Framework 5 i Spring Boot 2)
4 |
5 | ---
6 |
7 | ## O repozytorium
8 |
9 | Drogi Użytkowniku, repozytorium z którego korzystasz jest w pełni darmowe i dostęp do niego do niczego Cię nie zobowiązuje. Repozytorium to jest efektem ciężkiej pracy autora i kilku lat doświadczeń w prowadzeniu zajęć ze Spring Framework w polskich szkołach programowania. Było najwyżej oceniane przez wielu uczestników szkoleń i ze wszystkich w ten sposób przeze mnie przygotowanych zasłużyło na miano ... arcyrepozytorium :)
10 |
11 | Jeżeli Ci się spodoba i zaczniesz z niego korzystać to daj proszę gwiazdkę (_star na górze_) i dorzuć łacza (_watch na górze_), aby niczego nowego nie przegapić!
12 |
13 | ---
14 |
15 | ## O autorze
16 |
17 | Nazywam się Michał i od 20 lat programuję w języku Java. Od 9 lat robię to zawodowo. Pracowałem zarówno ze stosem technologicznym Java EE (5/6/7) jak i Spring (4/5). Od ponad dwóch lat jestem trenerem programowania ... podobno jednym z najlepszych w Polsce :)
18 |
19 | Więcej o moich doświadczeniach dowiesz się tutaj: [LinkedIn](https://www.linkedin.com/in/michal-kupisinski)
20 |
21 | ---
22 |
23 | ## Wspomóż
24 |
25 | Jednym z najbardziej wymagających uczniów jakich miałem w życiu była moja żona. Nie koniecznie przez opór materiału i trudności komunikacyjne, ale przez brak czasu na Jej nauczanie. Nasza rodzina nie kończy się na naszej dwójce :) Stąd jedyny sposób, aby mogła się nauczyć programowania było przygotowanie dla Niej materiałów do nauki, najlepszych na świecie. Efekt wspólnego wysiłku zamknęliśmy ostatecznie w kursie z podstaw programowania. Bez wątpienia najlepszym jaki jest :)
26 |
27 | Jeżeli uważasz, że taki kurs mógłby być dla Ciebie pomocny albo znasz kogoś dla kogo byłby pomocny (szczególnie na początku drogi), to skorzystaj lub poleć poniższy link:
28 |
29 | [Promocja: 50 godzin materiału najlepszej jakości w cenie 4 x CD-Action = 48,99 PLN](https://www.udemy.com/course/programowanie-w-javie-solidne-fundamenty/?couponCode=9BDD279891B9C7B313E5) <- Promocja ważna do 3 czerwca 2020
30 |
31 | 
32 |
33 | **Dziękuję za Twoje wsparcie i życzę Ci miłej pracy z tym repozytorium**
34 |
35 | ---
36 |
37 | ## Błędy i poprawki
38 |
39 | Repozytorium może zawierać drobne błędy... były one wprowadzane specjalnie, aby móc o nich dyskutować w trakcie zajęć stacjonarnych. Obecny tryb udostępnienia repozytorium nie umożliwia takiej pracy, więc błędy są eliminowane... ale jakieś drobne może gdzieś pozostały. Jak będę miał pewność, że nie ma już żadnych to tą notę usunę.
40 |
41 | ---
42 |
43 | ## Zmiany
44 |
45 | Repozytorium w ciągu najbliższych dni i tygodni będzie uzupełniane o brakujące rozwiązania i prawdopodobnie dalsze rozszerzenia. Bądź czujny i zaglądaj tutaj co jakiś czas :)
46 |
47 | ---
48 |
49 | ## Przygotowanie repozytorium
50 |
51 | 1. Repozytorium należy w pierwszej kolejności sforkować na swoje konto.
52 | 1. Utworzony fork należy skolonować poleceniem `git clone adres_twojego_forka`
53 |
54 | > Możesz też sklonować bezpośrednio główne repozytorium ale wtedy możliwa jest tylko praca lokalna na komputerze z repozytorium
55 |
56 | 1. Projekt, który jest opisany w repozytorium należy zrealizować w katalogu `project`.
57 | 1. W katalogu `project` znajduje się również referencyjny projekt (`honestit/demo`), który możesz śmiało wykorzystać.
58 |
59 | ---
60 |
61 | ## Wprowadzenie
62 |
63 | W ramach warsztatów zrealizujemy wspólnie prostą aplikację bazującą na Spring Framework. Będzie to serwis webowy umożliwiający użytkownikom publikacje ogłoszeń.
64 |
65 | Aplikacja będzie zawierała następujący zestaw funkcjonalności:
66 |
67 | 1. Obsługa użytkowników
68 | 1. Rejestracja nowych użytkowników
69 | 1. Logowanie
70 | 1. Wylogowanie
71 |
72 | 1. Obsługa ogłoszeń
73 | 1. Lista ostatnio dodanych ogłoszeń na stronie głównej
74 | 1. Lista wszystkich ogłoszeń zalogowanego użytkownika
75 | 1. Lista wszystkich ogłoszeń wybranego użytkownika
76 |
77 | ... i więcej!
78 |
79 | W trakcie prac nad tą prostą aplikacją wprowadzimy sobie podstawowe zagadnienia i techniki związane z:
80 | 1. **Spring Core/Context** - do obsługi wstrzykiwania zależności (IoC/DI),
81 | 1. **Spring MVC** - do obsługi żądań protokołu HTTP, w architekturze MVC,
82 | 1. **Spring Boot** - do szybkiego startu i automatycznej konfiguracji projektu,
83 | 1. **Spring Data JPA** - do integracji ze standardem JPA i obsługi warstwy bazodanowej,
84 | 1. **JSP** - do generowania dynamicznych widoków.
85 | 1. **Spring Security** - do obsługi warstwy bezpieczeństwa
86 |
87 | ---
88 |
89 | ## Moduł 1. Podstawowa konfiguracja projektu
90 |
91 | W pierwszej kolejności zajmiemy się przygotowaniem projektu do dalszych prac. Musimy zadbać o to, aby w naszym projekcie:
92 | - pojawiły się wszystkie zależności,
93 | - pojawiły się wszystkie wymagane konfiguracje.
94 |
95 | [Rozpocznij pracę z modułem](module_1/README.md)
96 |
97 | ---
98 |
99 | ## Moduł 2. Proces rejestracji i logowania
100 |
101 | Mamy podstawową konfigurację projektu i udało nam się go uruchomić. Będziemy realizować teraz kolejne funkcjonalności, a zaczniemy od rejestracji użytkownika oraz procesu logowania/wylogowania.
102 |
103 | Potrzebować będziemy:
104 | - klasy reprezentującej użytkownika, np. `User`,
105 | - klasy kontrolera Spring MVC obsługującej proces rejestracji, np. `RegistrationController`,
106 | - strony JSP z widokiem formularza rejestracji,
107 | - strony JSP z widokiem formularza logowania i jej obsługi w kontrolerze.
108 |
109 | [Rozpocznij pracę z modułem](module_2/README.md)
110 |
111 | ---
112 |
113 | ## Moduł 3. Dodawanie ogłoszeń i lista ogłoszeń
114 |
115 | W ramach zadań zrealizujemy dalszy zestaw funkcjonalności związany z obsługą ogłoszeń użytkowników. Zaczniemy od opcji dodania ogłoszenia oraz listy wszystkich ogłoszeń. Następnie przejdziemy do listy ogłoszeń per użytkownik oraz list ogłoszeń zalogowanego użytkownika. W ramach zadań dodatkowych możemy również wprowadzić edycję ogłoszenia oraz opcję jego usunięcia.
116 |
117 | [Rozpocznij pracę z modułem](module_3/README.md)
118 |
119 | ---
120 |
121 | ## Moduł 4. Rozszerzenia architektoniczne i technologiczne
122 |
123 | W ramach tej dodatkowej sekcji zrealizujemy zestaw rozszerzeń projektu, które w pierwszej kolejności będą poprawiały architekturę naszej aplikacji (rozszerzały ją), a w drugiej wprowadzały dodatkowe zagadnienia techniczne usprawniające i czyniące cały projekt bardziej atrakcyjny _w oczach innego programisty_.
124 |
125 | [Rozpocznij pracę z modułem](module_4/README.md)
126 |
127 | ---
128 |
129 | ### Dziękuję za wspólną pracę ;)
130 |
--------------------------------------------------------------------------------
/media/Programowanie-w-javie-solidne-fundamenty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/honestit/spring-intro/bf1bb64aacf7633d4705c6aae0cc2fd8d76352ee/media/Programowanie-w-javie-solidne-fundamenty.jpg
--------------------------------------------------------------------------------
/media/Tworzenie_projektu.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/honestit/spring-intro/bf1bb64aacf7633d4705c6aae0cc2fd8d76352ee/media/Tworzenie_projektu.PNG
--------------------------------------------------------------------------------
/module_1/README.md:
--------------------------------------------------------------------------------
1 | [< Powrót](../README.md)
2 |
3 | Wstecz | [Dalej](../module_2/README.md)
4 |
5 | ## Moduł 1. Podstawowa konfiguracja projektu
6 |
7 | W pierwszej kolejności zajmiemy się przygotowaniem projektu do dalszych prac. Musimy zadbać o to, aby w naszym projekcie:
8 | - pojawiły się wszystkie zależności,
9 | - pojawiły się wszystkie wymagane konfiguracje.
10 |
11 | ---
12 |
13 | ### Zadanie 1.1. Wygenerowanie projektu
14 |
15 | Korzystając ze Spring Boot możemy spróbować ręcznie stworzyć projekt, od zera, ale nie jest to potrzebne. Do automatycznego utworzenia projektu wykorzystamy stronę [start.spring.io](https://start.spring.io).
16 |
17 | Założenia:
18 | - tworzymy projekt Maven'a dla Java'y,
19 | - wybieramy najnowszą wersją Spring Boot,
20 | - określamy grupę `pl.honestit.spring`,
21 | - określamy artefakt `demo`,
22 | - dodajemy zależności do:
23 | - `Web`
24 | - `Security`
25 | - `JPA`
26 | - `MySQL` (lub `Postgres` lub `H2`)
27 |
28 | > Możemy również dodać zależności do `Lombok`, jeżeli biblioteka ta jest nam znana.
29 |
30 | Generujemy projekt i powstałe archiwum rozpakowujemy. Na podstawie tego archiwum za chwilę utworzymy nowy projekt w IntelliJ.
31 |
32 | 
33 |
34 | :hamster: [A tutaj znajdziesz startową wersję projektu](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/79134ecca449c993555a42121491fedfefcc6fe4/projects/honestit/demo)
35 |
36 | ---
37 |
38 | ### Zadanie 1.2. Utworzenie nowego projektu w IntelliJ
39 |
40 | W IntelliJ tworzymy nowy projekt na podstawie istniejących źródeł, a więc rozpakowanego archiwum wcześniej wygenerowanego projektu.
41 |
42 | Należy pamiętać, aby w projekcie były ustawione następujące elementy:
43 | - wersja SDK na Java `1.8` lub `1.11`,
44 | - katalog `src/main/java` oznaczony jako katalog ze źródłami (_Sources Root_),
45 | - katalog `src/main/resources` oznaczony jako katalog z zasobami (_Resources Root_),
46 | - utworzony katalog `src/main/webapp`, w którym będziemy tworzyć widoki JSP.
47 |
48 | :hamster: [Mam dla Ciebie skonfigurowany projekt z tymi wszystkimi pitu-pitu!](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/062f3feec0803529467bfd52b2974e69ce42239d/projects/honestit/demo)
49 |
50 | ---
51 |
52 | ### Zadanie 1.3. Konfiguracja Maven'a pod technologię JSP
53 |
54 | Ze względu na to, że w projekcie będziemy wykorzystywać strony JSP, to musimy rozszerzyć zestaw wykorzystywanych zależności o bibliotekę JSTL oraz wsparcie dla przetwarzania stron JSP. Strona `start.spring.io` nie umożliwia nam dodania takich zależności.
55 |
56 | 1. Do pliku `pom.xml` dodajemy poniższe zależności:
57 |
58 | **Biblioteka JSTL:**
59 |
60 | ```xml
61 |
62 | jstl
63 | jstl
64 | 1.2
65 |
66 | ```
67 |
68 | **Wsparcie dla stron JSP:**
69 |
70 | ```xml
71 |
72 | org.apache.tomcat.embed
73 | tomcat-embed-jasper
74 |
75 | ```
76 |
77 | [Rozwiązanie zadania](resolutions/1.3.md)
78 |
79 | :hamster: [Tutaj jest cały projekt, który udało nam się do tej pory ogarnąć](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/151319c76c5e7a24857969c513243fe136a45d51/projects/honestit/demo)
80 |
81 | :hamster: [... a tutaj sam plik pom.xml](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/blob/151319c76c5e7a24857969c513243fe136a45d51/projects/honestit/demo/pom.xml)
82 |
83 | ---
84 |
85 | ### Zadanie 1.4. Test działania
86 |
87 | W celu zweryfikowania czy projekt został poprawnie skonfigurowany przygotujemy sobie testową stronę powitalną. Będzie to zwykła strona HTML. Można wykorzystać poniższy kod strony lub napisać własną:
88 |
89 | ```html
90 |
91 |
92 |
93 |
94 | Testowa strona główna
95 |
96 |
97 | Witaj w Spring'u
98 |
99 |
100 | ```
101 |
102 | Stronę zapiszmy jako plik `index.html` w katalogu `webapp`. Ważna jest dokładnie taka nazwa pliku oraz jego położenia, ponieważ w ten sposób będzie on funkcjonował w roli domyślnej strony głównej.
103 |
104 | > Później plik ten usuniemy i przygotujemy prawdziwą stronę główną.
105 |
106 | Możemy teraz przystąpić do uruchomienia projektu. W tym celu musimy znaleźć w katalogu `java` (a więc katalogu z naszymi źródłami) klasę `pl.honestit.spring.demo.DemoApplication`. Nazwa tej klasy jest połączeniem nazwy artefaktu, który wybraliśmy oraz słowa `Application`. Zobaczymy, że w klasie mamy pojedynczą metodę `main`, spełniającą wymogi głównej metody uruchomieniowej. Nie pozostaje nic innego jak odpalić tą metodę.
107 |
108 | Kilka uwaga:
109 | - nasza klasa posiada adnotację `@SpringBootApplication` - jest to adnotacja, która czyni całą magię Spring Boot'a, a magią tą jest dostarczenie ogromu konfiguracji domyślnych, których sami nie musimy przygotowywać.
110 | - naszą klasę uruchamia metoda statyczna `run` z klasy `SpringApplication`,
111 | - **wszystko w naszym projekcie będzie działać tak długo, aż będziemy tworzyć nowe klasy w podpakietach pakietu `demo`, a więc poniżej klasy `DemoApplication`**
112 |
113 | Startujemy i ... czy uruchomienie aplikacji powiodło się?
114 |
115 | [Rozwiązanie zadania](resolutions/1.4.md)
116 |
117 | :hamster: [Cały projekt](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/d0b31c95b7be3fb756571dfc40c3049353f51495/projects/honestit/demo)
118 |
119 | :hamster: [... i taką stronę dorzuciłem!](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/blob/d0b31c95b7be3fb756571dfc40c3049353f51495/projects/honestit/demo/src/main/webapp/index.html)
120 |
121 | ---
122 |
123 | ### Zadanie 1.5. Konfiguracja bazy danych
124 |
125 | W poprzednim kroku nasza aplikacja nie uruchomiła się z powodu błędu braku skonfigurowanego źródła danych. Tworząc projekt wybraliśmy zależności do JPA a te, aby poprawnie się skonfigurować, potrzebują **definicji źródła danych**, tzw _datasource_. Przystąpimy teraz do konfiguracji bazy danych w aplikacji.
126 |
127 | Aplikacja oparta na Spring Boot wprowadza nam pojedynczy plik konfiguracyjny do ustawienia wszystkich możliwych właściwości. Znajdziemy go w katalogu `resources` pod nazwą `application.properties`.
128 |
129 | > Zwróć uwagę, że środowisko IntelliJ posiada wsparcie dla tego pliku, a więc udostępnia bardzo bogate podpowiedzi kontekstowe. Można w ten sposób zapoznać się z wieloma dostępnymi opcjami konfiguracyjnymi.
130 |
131 | Za konfigurację źródeł danych odpowiadają następujące parametry:
132 | - `spring.datasource.url`: określający ścieżkę do bazy danych,
133 | - `spring.datasource.username`: określający nazwę użytkownika do bazy danych,
134 | - `spring.datasource.password`: określający hasło użytkownika do bazy danych,
135 | - `spring.datasource.driver-class-name`: określający klasę sterownika bazy danych,
136 | - `spring.jpa.database-platform`: określający dialekt, którego ma użyć Hibernate w komunikacji z bazą danych,
137 |
138 | W zależności od tego jak mamy skonfigurowaną bazę danych (jaki host, port, nazwa bazy danych, użytkownik i hasło), to pierwsze trzy parametry będą się zmieniać. Pozostałe będą zależne od wersji serwera bazy danych. Poniżej jest zaprezentowana konfiguracja dla serwera MySQL 8.0.11, bazy o nazwie `spring_intro`, użytkownika `root` i hasła `pass`:
139 |
140 | ```properties
141 | # Konfiguracja bazy danych MySQL
142 | spring.datasource.url=jdbc:mysql://localhost:5432/spring_intro?useSSL=false&serverTimezone=UTC
143 | spring.datasource.username=root
144 | spring.datasource.password=pass
145 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
146 | spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
147 | ```
148 |
149 | Jeżeli dodatkowo chcemy, aby Hibernate pokazywał w logach aplikacji używane zapytania SQL oraz automatycznie tworzył/aktualizował tabele na bazie danych, to możemy dorzucić poniższe konfiguracje:
150 |
151 | ```properties
152 | # Konfiguracja JPA
153 | spring.jpa.hibernate.ddl-auto=update
154 | spring.jpa.show-sql=true
155 | spring.jpa.properties.hibernate.format_sql=true
156 | ```
157 |
158 | Na samym końcu możemy uzupełnić zestaw konfiguracji związanych z kodowaniem znaków:
159 |
160 | ```properties
161 | # Kodowanie znaków w połączeniu do bazy danych
162 | spring.jpa.properties.useUnicode=true
163 | spring.jpa.properties.characterEncoding=utf8
164 | spring.jpa.properties.CharSet=utf8
165 | ```
166 |
167 | Po uzupełnienie tych konfiguracji możemy ponownie wystartować projekt i zobaczyć czy tym razem uruchomi się bez problemu. W logach powinna pojawić się linia `Started demoApplication in ...`, co będzie dla nas sygnałem, że aplikacja wystartowała!
168 |
169 | Spróbujmy teraz wejść na stronę [localhost:8080/index.html](http://localhost:8080/index.html)
170 |
171 | Co stało się tym razem?
172 |
173 | [Rozwiązanie zadania](resolutions/1.5.md)
174 |
175 | :hamster: [Na tą chwilę projekt wygląda tak](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/d17c36e27e76d3f570b6f366052895078463432d/projects/honestit/demo)
176 |
177 | :hamster: [... a sam plik application.properties tak](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/blob/d17c36e27e76d3f570b6f366052895078463432d/projects/honestit/demo/src/main/resources/application.properties)
178 |
179 | :hamster: [... chociaż potem potrzebował małej poprawki tutaj](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/commit/44436c7fe11af0827158f2ccc87c38808850eabd)
180 |
181 | ---
182 |
183 | ### Zadanie 1.6. Konfiguracja użytkownika testowego w warstwie Security
184 |
185 | Zdecydowaliśmy się na etapie generowania projektu na zależności do `Security`, więc nasza aplikacja została automatycznie zabezpieczona w pewnym podstawowym zakresie. Między innymi: wejście na każdą stronę wymaga wcześniejszego zalogowania. Pozostaje tylko pytanie na jakiego użytkownika skoro jeszcze żaden nie istnieje?
186 |
187 | W kolejnych krokach zmodyfikujemy podstawową konfigurację bezpieczeństwa o własne ustawienia, ale na razie potrzebujemy prostego użytkownika testowego, na którego będziemy mogli się zalogować.
188 |
189 | Skoro mowa o konfiguracji, to ponownie sięgamy do pliku `application.properties`. Potrzebujemy parametrów:
190 | - `spring.security.user.name` do określenia nazwy domyślnego użytkownika warstwy bezpieczeństwa (testowego),
191 | - `spring.security.user.password` do określenia hasła domyślnego użytkownika warstwy bezpieczeństwa (testowego),
192 | - `spring.security.user.roles` do określenia ról domyślnego użytkownika warstwy bezpieczeństwa (testowego).
193 |
194 | Wspomniane parametry możemy uzupełnić w następujący sposób:
195 |
196 | ```properties
197 | spring.security.user.name=user
198 | spring.security.user.password=pass
199 | spring.security.user.roles=USER
200 | ```
201 |
202 | Kolejny raz odpalmy aplikację i spróbujmy wejść na stronę [localhost:8080/index.html](http://localhost:8080/index.html).
203 |
204 | Tym razem już wszystko powinno zadziałać!
205 |
206 | [Rozwiązanie zadania](resolutions/1.6.md)
207 |
208 | :hamster: [Przynoszę aktualną wersję projektu!](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/tree/233b2b1b704c91a774681455f2ba89428864c192/projects/honestit/demo)
209 |
210 | :hamster: [... a sam plik application.properties tak się zmienił](https://github.com/honestit/SDA_JAVA_WRO_23_SPRING_INTRO/blob/233b2b1b704c91a774681455f2ba89428864c192/projects/honestit/demo/src/main/resources/application.properties)
211 |
212 | ---
213 |
214 | ### Podsumowanie
215 |
216 | Mamy już poprawnie skonfigurowany projekt wykorzystujący wszystkie wymienione technologie. Możemy go uruchomić, ale jeszcze nie wiele co _widocznego_ się w nim dzieje. W kolejnym zadaniu przejdziemy przez dalsze kroki, które przeprowadzą nas przez nasz własny proces rejestracji i logowania użytkowników. Jednocześnie zaczniemy wykorzystywać Spring MVC i jego najważniejsze elementy: kontrolery.
217 |
218 | ---
219 |
220 | Wstecz | [Dalej](../module_2/README.md)
--------------------------------------------------------------------------------
/module_1/resolutions/1.3.md:
--------------------------------------------------------------------------------
1 | **Plik `pom.xml` z uwzględnieniem dodatkowych zależności:**
2 |
3 | ```xml
4 |
5 |
7 | 4.0.0
8 |
9 | org.springframework.boot
10 | spring-boot-starter-parent
11 | 2.2.0.RELEASE
12 |
13 |
14 | pl.honestit.spring
15 | demo
16 | 0.0.1-SNAPSHOT
17 | demo
18 |
19 |
20 | 1.8
21 |
22 |
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-data-jpa
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-security
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-web
35 |
36 |
37 |
38 | jstl
39 | jstl
40 | 1.2
41 |
42 |
43 |
44 | org.apache.tomcat.embed
45 | tomcat-embed-jasper
46 |
47 |
48 |
49 | mysql
50 | mysql-connector-java
51 | runtime
52 |
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-starter-test
57 | test
58 |
59 |
60 | org.springframework.security
61 | spring-security-test
62 | test
63 |
64 |
65 |
66 |
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-maven-plugin
71 |
72 |
73 |
74 |
75 |
76 |
77 | ```
--------------------------------------------------------------------------------
/module_1/resolutions/1.4.md:
--------------------------------------------------------------------------------
1 | **Strona testowa `index.html` w katalogu `webapp`:**
2 |
3 | ```html
4 |
5 |
6 |
7 |
8 | Testowa strona główna
9 |
10 |
11 | Witaj w Spring'u
12 |
13 |
14 | ```
--------------------------------------------------------------------------------
/module_1/resolutions/1.5.md:
--------------------------------------------------------------------------------
1 | **Konfiguracja aplikacji w pliku `application.properties`:**
2 |
3 | ```properties
4 | #
5 | # Konfiguracja bazy danych MySQL
6 | #
7 | spring.datasource.url=jdbc:mysql://localhost:5432/spring_intro?useSSL=false&serverTimezone=UTC
8 | # --- Nazwę użytkownika podstawiamy swoją
9 | spring.datasource.username=root
10 | # --- Hasło podstawiamy swoje
11 | spring.datasource.password=pass
12 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
13 | spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
14 |
15 | #
16 | # Konfiguracja JPA/Hibernate
17 | #
18 | spring.jpa.hibernate.ddl-auto=update
19 | spring.jpa.show-sql=true
20 | spring.jpa.properties.hibernate.format_sql=true
21 |
22 | #
23 | # Kodowanie znaków w połączeniu do bazy danych
24 | #
25 | spring.jpa.properties.useUnicode=true
26 | spring.jpa.properties.characterEncoding=utf8
27 | spring.jpa.properties.CharSet=utf8
28 | ```
--------------------------------------------------------------------------------
/module_1/resolutions/1.6.md:
--------------------------------------------------------------------------------
1 | **Konfiguracja aplikacji z uwzględnieniem użytkownika testowego dla Spring Security, w pliku `application.properties`:**
2 |
3 | ```properties
4 | #
5 | # Konfiguracja bazy danych MySQL
6 | #
7 | spring.datasource.url=jdbc:mysql://localhost:5432/spring_intro?useSSL=false&serverTimezone=UTC
8 | # --- Nazwę użytkownika podstawiamy swoją
9 | spring.datasource.username=root
10 | # --- Hasło podstawiamy swoje
11 | spring.datasource.password=pass
12 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
13 | spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
14 |
15 | #
16 | # Konfiguracja JPA/Hibernate
17 | #
18 | spring.jpa.hibernate.ddl-auto=update
19 | spring.jpa.show-sql=true
20 | spring.jpa.properties.hibernate.format_sql=true
21 |
22 | #
23 | # Kodowanie znaków w połączeniu do bazy danych
24 | #
25 | spring.jpa.properties.useUnicode=true
26 | spring.jpa.properties.characterEncoding=utf8
27 | spring.jpa.properties.CharSet=utf8
28 |
29 | #
30 | # Konfiguracja bezpieczeństwa (Spring Security)
31 | #
32 | spring.security.user.name=user
33 | spring.security.user.password=pass
34 | spring.security.user.roles=USER
35 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.1.md:
--------------------------------------------------------------------------------
1 | **Kod encji `User`:**
2 |
3 | ```java
4 | package pl.honesit.spring.demo.model.domain;
5 |
6 | import javax.persistence.*;
7 | import java.util.Objects;
8 |
9 | @Entity
10 | @Table(name = "users")
11 | public class User {
12 |
13 | @Id
14 | @GeneratedValue(strategy = GenerationType.IDENTITY)
15 | private Long id;
16 | @Column(unique = true, nullable = false)
17 | private String username;
18 | @Column(nullable = false)
19 | private String password;
20 | @Column(name = "first_name")
21 | private String firstName;
22 | @Column(name = "last_name")
23 | private String lastName;
24 | @Column(nullable = false)
25 | private Boolean active;
26 |
27 | @Override
28 | public boolean equals(Object o) {
29 | if (this == o) return true;
30 | if (o == null || getClass() != o.getClass()) return false;
31 | User user = (User) o;
32 | return Objects.equals(id, user.id) &&
33 | Objects.equals(username, user.username);
34 | }
35 |
36 | @Override
37 | public int hashCode() {
38 |
39 | return Objects.hash(id, username);
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "User{" +
45 | "id=" + id +
46 | ", username='" + username + '\'' +
47 | ", password='" + password + '\'' +
48 | ", firstName='" + firstName + '\'' +
49 | ", lastName='" + lastName + '\'' +
50 | ", active='" + active + '\'' +
51 | '}';
52 | }
53 |
54 | public Long getId() {
55 | return id;
56 | }
57 |
58 | public void setId(Long id) {
59 | this.id = id;
60 | }
61 |
62 | public String getUsername() {
63 | return username;
64 | }
65 |
66 | public void setUsername(String username) {
67 | this.username = username;
68 | }
69 |
70 | public String getPassword() {
71 | return password;
72 | }
73 |
74 | public void setPassword(String password) {
75 | this.password = password;
76 | }
77 |
78 | public String getFirstName() {
79 | return firstName;
80 | }
81 |
82 | public void setFirstName(String firstName) {
83 | this.firstName = firstName;
84 | }
85 |
86 | public String getLastName() {
87 | return lastName;
88 | }
89 |
90 | public void setLastName(String lastName) {
91 | this.lastName = lastName;
92 | }
93 |
94 | public Boolean getActive() {
95 | return active;
96 | }
97 |
98 | public void setActive(Boolean active) {
99 | this.active = active;
100 | }
101 | }
102 |
103 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.2.md:
--------------------------------------------------------------------------------
1 | **Kod klasy kontrolera `RegistrationController`:**
2 |
3 | ```java
4 | package pl.honesit.spring.demo.controllers;
5 |
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import pl.alx.spring.demo.model.domain.User;
11 |
12 | @Controller
13 | @RequestMapping("/register")
14 | public class RegistrationController {
15 |
16 | @GetMapping
17 | public String preparepRegistrationPage() {
18 | // TODO
19 | return "";
20 | }
21 |
22 |
23 | @PostMapping
24 | public String processRegistrationPage() {
25 | // TODO
26 | return "";
27 | }
28 |
29 | }
30 |
31 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.3.md:
--------------------------------------------------------------------------------
1 | **Plik `pom.xml` z dodatkowymi zależnościami:**
2 |
3 | ```xml
4 |
5 |
7 | 4.0.0
8 |
9 | org.springframework.boot
10 | spring-boot-starter-parent
11 | 2.2.0.RELEASE
12 |
13 |
14 | pl.honesit.spring
15 | demo
16 | 0.0.1-SNAPSHOT
17 | demo
18 | Demo project for Spring Boot
19 |
20 |
21 | 1.8
22 |
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-data-jpa
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-security
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 |
39 | mysql
40 | mysql-connector-java
41 | runtime
42 |
43 |
44 |
45 | jstl
46 | jstl
47 | 1.2
48 |
49 |
50 |
51 | org.springframework.security
52 | spring-security-taglibs
53 | 5.0.6.RELEASE
54 |
55 |
56 |
57 | org.apache.tomcat.embed
58 | tomcat-embed-jasper
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-starter-test
64 | test
65 |
66 |
67 | org.springframework.security
68 | spring-security-test
69 | test
70 |
71 |
72 |
73 |
74 |
75 |
76 | org.springframework.boot
77 | spring-boot-maven-plugin
78 |
79 |
80 |
81 |
82 |
83 |
84 | ```
85 |
86 | **Strona widoku `registration-page.jsp`:**
87 |
88 | ```jsp
89 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
90 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
91 |
92 |
93 |
94 |
96 |
99 |
102 |
105 |
106 |
107 |
108 |
109 |
110 |
Rejestracja
111 |
112 |
113 |
144 |
145 |
146 |
147 | ```
148 |
149 | **Kod kontrolera `RegistrationController` z obsługą widoku w metodzie `GET`:**
150 |
151 | ```java
152 | package pl.honestit.spring.demo.controllers;
153 |
154 | import org.springframework.stereotype.Controller;
155 | import org.springframework.web.bind.annotation.GetMapping;
156 | import org.springframework.web.bind.annotation.PostMapping;
157 | import org.springframework.web.bind.annotation.RequestMapping;
158 |
159 | @Controller
160 | @RequestMapping("/register")
161 | public class RegistrationController {
162 |
163 | @GetMapping
164 | public String preparepRegistrationPage() {
165 | return "/WEB-INF/views/registration-page.jsp";
166 | }
167 |
168 | @PostMapping
169 | public String processRegistrationPage() {
170 | // TODO
171 | return "";
172 | }
173 |
174 | }
175 |
176 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.4.md:
--------------------------------------------------------------------------------
1 | **Kod repozytorium `UserRepository`:**
2 |
3 | ```java
4 | package pl.honestit.spring.demo.model.repositories;
5 |
6 | import org.springframework.data.jpa.repository.JpaRepository;
7 | import pl.honestit.spring.demo.model.domain.User;
8 |
9 | public interface UserRepository extends JpaRepository {
10 |
11 | }
12 | ```
13 |
14 | **Kod kontrolera `RegistrationController` i metody `POST`:**
15 |
16 | ```java
17 | package pl.honestit.spring.demo.controllers;
18 |
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.stereotype.Controller;
21 | import org.springframework.web.bind.annotation.GetMapping;
22 | import org.springframework.web.bind.annotation.PostMapping;
23 | import org.springframework.web.bind.annotation.RequestMapping;
24 | import pl.honestit.spring.demo.model.repositories.UserRepository;
25 | import pl.honestit.spring.demo.model.domain.User;
26 |
27 | import javax.servlet.http.HttpSession;
28 |
29 | @Controller
30 | @RequestMapping("/register")
31 | public class RegistrationController {
32 |
33 | private final UserRepository userRepository;
34 |
35 | @Autowired
36 | public RegistrationController(UserRepository userRepository) {
37 | this.userRepository = userRepository;
38 | }
39 |
40 | @GetMapping
41 | public String preparepRegistrationPage() {
42 | return "/WEB-INF/views/registration-page.jsp";
43 | }
44 |
45 | @PostMapping
46 | public String processRegistrationPage(String username,
47 | String password,
48 | String firstName,
49 | String lastName) {
50 | User user = new User();
51 | user.setPassword(password);
52 | user.setUsername(username);
53 | user.setFirstName(firstName);
54 | user.setLastName(lastName);
55 | user.setActive(true);
56 |
57 | userRepository.save(user);
58 | return "redirect:/index.html";
59 | }
60 |
61 | }
62 |
63 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.5.md:
--------------------------------------------------------------------------------
1 | **Klasa `SecurityConfiguration` z konfiguracją autoryzacji:**
2 |
3 | ```java
4 | package pl.honesit.spring.demo.config;
5 |
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
9 |
10 | @Configuration
11 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
12 |
13 | @Override
14 | protected void configure(HttpSecurity http) throws Exception {
15 | http.authorizeRequests()
16 | .antMatchers("/register").permitAll()
17 | .anyRequest().authenticated()
18 | .and()
19 | .formLogin()
20 | .defaultSuccessUrl("/index.html")
21 | .and()
22 | .logout()
23 | .logoutSuccessUrl("/index.html");
24 | }
25 | }
26 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.6.md:
--------------------------------------------------------------------------------
1 | **Udostępnienie bean'a do szyfrowania hasła w klasie `SecurityConfiguration`:**
2 |
3 | ```java
4 | package pl.honestit.spring.demo.config;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
12 | import org.springframework.security.crypto.password.PasswordEncoder;
13 |
14 | import javax.sql.DataSource;
15 |
16 | @Configuration
17 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
18 |
19 | @Bean
20 | public PasswordEncoder passwordEncoder() {
21 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
22 | }
23 |
24 | @Override
25 | protected void configure(HttpSecurity http) throws Exception {
26 | http.authorizeRequests()
27 | .antMatchers("/register").permitAll()
28 | .anyRequest().authenticated()
29 | .and()
30 | .formLogin()
31 | .defaultSuccessUrl("/index.html")
32 | .and()
33 | .logout()
34 | .logoutSuccessUrl("/index.html");
35 | }
36 | }
37 |
38 | ```
39 |
40 | **Wykorzystania bean'a do szyfrowania w klasie `RegistrationController`:**
41 |
42 | ```java
43 | package pl.honestit.spring.demo.controllers;
44 |
45 | import org.springframework.beans.factory.annotation.Autowired;
46 | import org.springframework.security.crypto.password.PasswordEncoder;
47 | import org.springframework.stereotype.Controller;
48 | import org.springframework.web.bind.annotation.GetMapping;
49 | import org.springframework.web.bind.annotation.PostMapping;
50 | import org.springframework.web.bind.annotation.RequestMapping;
51 | import pl.honestit.spring.demo.model.dal.UserRepository;
52 | import pl.honestit.spring.demo.model.domain.User;
53 |
54 | import javax.servlet.http.HttpSession;
55 |
56 | @Controller
57 | @RequestMapping("/register")
58 | public class RegistrationController {
59 |
60 | private final UserRepository userRepository;
61 | private final PasswordEncoder passwordEncoder;
62 |
63 | @Autowired
64 | public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
65 | this.userRepository = userRepository;
66 | this.passwordEncoder = passwordEncoder;
67 | }
68 |
69 | @GetMapping
70 | public String preparepRegistrationPage() {
71 | return "/WEB-INF/views/registration-page.jsp";
72 | }
73 |
74 | @PostMapping
75 | public String processRegistrationPage(String username,
76 | String password,
77 | String firstName,
78 | String lastName) {
79 | User user = new User();
80 | String encodedPassword = passwordEncoder.encode(password);
81 | user.setPassword(encodedPassword);
82 | user.setUsername(username);
83 | user.setFirstName(firstName);
84 | user.setLastName(lastName);
85 | user.setActive(true);
86 |
87 | userRepository.save(user);
88 | return "redirect:/index.html";
89 | }
90 |
91 | }
92 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.7.md:
--------------------------------------------------------------------------------
1 | **Rozszerzona konfiguracja klasy `SecurityConfig` uwzględniająca obsługę uwierzytelnienia w oparciu
2 | o zapytania do bazy danych:**
3 |
4 | ```java
5 | package pl.honestit.spring.demo.config;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
14 | import org.springframework.security.crypto.password.PasswordEncoder;
15 |
16 | import javax.sql.DataSource;
17 |
18 | @Configuration
19 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
20 |
21 | private final DataSource dataSource;
22 |
23 | @Autowired
24 | public SecurityConfiguration(DataSource dataSource) {
25 | this.dataSource = dataSource;
26 | }
27 |
28 | @Bean
29 | public PasswordEncoder passwordEncoder() {
30 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
31 | }
32 |
33 | @Override
34 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
35 | auth.jdbcAuthentication()
36 | .dataSource(dataSource)
37 | .passwordEncoder(passwordEncoder())
38 | .usersByUsernameQuery("SELECT username, password, active FROM users WHERE username = ?")
39 | .authoritiesByUsernameQuery("SELECT username, 'ROLE_USER' FROM users WHERE username = ?");
40 | }
41 |
42 | @Override
43 | protected void configure(HttpSecurity http) throws Exception {
44 | http.authorizeRequests()
45 | .antMatchers("/register").permitAll()
46 | .anyRequest().authenticated()
47 | .and()
48 | .formLogin()
49 | .defaultSuccessUrl("/index.html")
50 | .and()
51 | .logout()
52 | .logoutSuccessUrl("/index.html");
53 | }
54 | }
55 |
56 | ```
--------------------------------------------------------------------------------
/module_2/resolutions/2.8.md:
--------------------------------------------------------------------------------
1 | **Klasa kontrolera `LoginController`, która obsługę widok:**
2 |
3 | ```java
4 | package pl.honestit.spring.demo.controllers;
5 |
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 |
10 | @Controller
11 | @RequestMapping("/login")
12 | public class LoginController {
13 |
14 | @GetMapping
15 | public String prepareLoginPage() {
16 | return "/WEB-INF/views/login-page.jsp";
17 | }
18 | }
19 | ```
20 |
21 | **Strona jsp `login-page.jsp` zawierająca formularz logowania:**
22 |
23 | ```jsp
24 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
25 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
26 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
Logowanie
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Błędne dane logowania!
49 |
50 | ×
51 |
52 |
53 |
54 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | ```
74 |
75 | **Zmodyfikowana konfiguracja bezpieczeństwa bazująca na własnym formularzu:**
76 |
77 | ```java
78 | package pl.honestit.spring.demo.config;
79 |
80 | import org.springframework.beans.factory.annotation.Autowired;
81 | import org.springframework.context.annotation.Bean;
82 | import org.springframework.context.annotation.Configuration;
83 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
84 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
85 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
86 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
87 | import org.springframework.security.crypto.password.PasswordEncoder;
88 |
89 | import javax.sql.DataSource;
90 |
91 | @Configuration
92 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
93 |
94 | private final DataSource dataSource;
95 |
96 | @Autowired
97 | public SecurityConfiguration(DataSource dataSource) {
98 | this.dataSource = dataSource;
99 | }
100 |
101 | @Bean
102 | public PasswordEncoder passwordEncoder() {
103 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
104 | }
105 |
106 | @Override
107 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
108 | auth.jdbcAuthentication()
109 | .dataSource(dataSource)
110 | .passwordEncoder(passwordEncoder())
111 | .usersByUsernameQuery("SELECT username, password, active FROM users WHERE username = ?")
112 | .authoritiesByUsernameQuery("SELECT username, 'ROLE_USER' FROM users WHERE username = ?");
113 | }
114 |
115 | @Override
116 | protected void configure(HttpSecurity http) throws Exception {
117 | http.authorizeRequests()
118 | .antMatchers("/register").permitAll()
119 | .antMatchers("/login").anonymous()
120 | .anyRequest().authenticated()
121 | .and()
122 | .formLogin()
123 | .loginPage("/login")
124 | .defaultSuccessUrl("/index.html")
125 | .and()
126 | .logout()
127 | .logoutUrl("/logout")
128 | .logoutSuccessUrl("/index.html")
129 | }
130 | }
131 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.1.md:
--------------------------------------------------------------------------------
1 | Encja reprezentująca nasze ogłoszenie:
2 |
3 | ```java
4 | package pl.honestit.spring.demo.model.domain;
5 |
6 | import javax.persistence.*;
7 | import java.time.LocalDateTime;
8 | import java.util.Objects;
9 |
10 | @Entity
11 | @Table(name = "adverts")
12 | public class Advert {
13 |
14 | @Id
15 | @GeneratedValue(strategy = GenerationType.IDENTITY)
16 | private Long id;
17 | @Column(nullable = false)
18 | private String title;
19 | @Column(columnDefinition = "TEXT")
20 | private String description;
21 | private LocalDateTime posted;
22 | @ManyToOne
23 | @JoinColumn(name = "owner_id")
24 | private User owner;
25 | @Column(name = "owner_id", insertable = false, updatable = false)
26 | private Long ownerId;
27 |
28 | public Long getId() {
29 | return id;
30 | }
31 |
32 | public void setId(Long id) {
33 | this.id = id;
34 | }
35 |
36 | public String getTitle() {
37 | return title;
38 | }
39 |
40 | public void setTitle(String title) {
41 | this.title = title;
42 | }
43 |
44 | public String getDescription() {
45 | return description;
46 | }
47 |
48 | public void setDescription(String description) {
49 | this.description = description;
50 | }
51 |
52 | public LocalDateTime getPosted() {
53 | return posted;
54 | }
55 |
56 | public void setPosted(LocalDateTime posted) {
57 | this.posted = posted;
58 | }
59 |
60 | public User getOwner() {
61 | return owner;
62 | }
63 |
64 | public void setOwner(User owner) {
65 | this.owner = owner;
66 | }
67 |
68 | @Override
69 | public boolean equals(Object o) {
70 | if (this == o) return true;
71 | if (o == null || getClass() != o.getClass()) return false;
72 | Advert advert = (Advert) o;
73 | return Objects.equals(id, advert.id);
74 | }
75 |
76 | @Override
77 | public int hashCode() {
78 |
79 | return Objects.hash(id);
80 | }
81 |
82 | @Override
83 | public String toString() {
84 | return "Advert{" +
85 | "id=" + id +
86 | ", title='" + title + '\'' +
87 | ", description='" + description + '\'' +
88 | ", posted=" + posted +
89 | ", ownerId=" + ownerId +
90 | '}';
91 | }
92 | }
93 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.2.md:
--------------------------------------------------------------------------------
1 | Interfejs `AdvertRepository` do obsługi encji `Advert`:
2 |
3 | ```java
4 | package pl.honestit.spring.demo.model.repositories;
5 |
6 | import org.springframework.data.jpa.repository.JpaRepository;
7 | import pl.honestit.spring.demo.model.domain.Advert;
8 |
9 | public interface AdvertRepository extends JpaRepository {
10 | }
11 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.3.md:
--------------------------------------------------------------------------------
1 | Kontroler `HomePageController`, który będzie dostarczał obsługę strony głównej:
2 |
3 | ```java
4 | package pl.honestit.spring.demo.controllers;
5 |
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 |
9 | @Controller
10 | @RequestMapping("/")
11 | public class HomePageController {
12 | }
13 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.4.md:
--------------------------------------------------------------------------------
1 | Uzupełniony kod kontrolera `HomePageController` o obsługę żądania `GET` na stronę główną:
2 |
3 | ```java
4 | package pl.honestit.spring.demo.controllers;
5 |
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import pl.honestit.spring.demo.model.domain.Advert;
11 | import pl.honestit.spring.demo.model.repositories.AdvertRepository;
12 |
13 | import java.util.List;
14 |
15 | @Controller
16 | @RequestMapping("/")
17 | public class HomePageController {
18 |
19 | private final AdvertRepository advertRepository;
20 |
21 | public HomePageController(AdvertRepository advertRepository) {
22 | this.advertRepository = advertRepository;
23 | }
24 |
25 | @GetMapping
26 | public String prepareHomePage(Model model) {
27 | List allAdverts = advertRepository.findAllByOrderByPostedDesc();
28 | model.addAttribute("adverts", allAdverts);
29 | return "home-page";
30 | }
31 | }
32 |
33 | ```
34 |
35 | ---
36 |
37 | Uzupełniony kod interfejsu `AdvertRepository` o metodę wyszukującą wszystkie ogłoszenia posortowane po dacie utworzenia, od najnowszego:
38 |
39 | ```java
40 | package pl.honestit.spring.demo.model.repositories;
41 |
42 | import org.springframework.data.jpa.repository.JpaRepository;
43 | import pl.honestit.spring.demo.model.domain.Advert;
44 |
45 | import java.util.List;
46 |
47 | public interface AdvertRepository extends JpaRepository {
48 |
49 | List findAllByOrderByPostedDesc();
50 | }
51 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.5.md:
--------------------------------------------------------------------------------
1 | Kod strony `home-page.jsp`, którą umieszczamy w katalogu `webapp/WEB-INF/views`:
2 |
3 | ```jsp
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
5 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
6 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Dodaj ogłoszenie
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | <%-- Tutaj formularz dodawania nowego ogłoszenia (PÓŹNIEJ) --%>
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
Lista ogłoszeń
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Lp.
47 | Tytuł
48 | Treść
49 | Autor
50 | Data dodania
51 |
52 |
53 |
54 | ${stat.count}
55 | ${advert.title}
56 | ${advert.description}
57 | ${advert.owner.username}
58 | ${advert.posted}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | ```
69 |
70 | ---
71 |
72 | Przykładowe zapytania SQL, którymi możemy uzupełnić ogłoszenia (pod warunkiem, że mamy w bazie użytkownika o id = 1):
73 |
74 | ```SQL
75 | INSERT INTO adverts(title, description, owner_id, posted) VALUES ('Sprzedam dom', 'Sprzedam dom 120 m2 z działką 500m2. Okolice Wrocławia', 1, '2019-07-03 12:00:00');
76 | INSERT INTO adverts(title, description, owner_id, posted) VALUES ('Oddam psa', 'Oddam w dobre ręcę pieska razy doberman, 80kg', 1, '2019-07-03 12:30:00');
77 | INSERT INTO adverts(title, description, owner_id, posted) VALUES ('Kupię odkurzacz', 'Kupie odkurzacz, używany nie dłużej niż 2 lata, z czystymi workami', 1, '2019-07-03 13:17:00');
78 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.6.md:
--------------------------------------------------------------------------------
1 | Zmodyfikowana konfiguracja w klasie `SecurityConfiguration` (zmieniła się metoda `configure(HttpSecurity)`:
2 |
3 | ```java
4 | package pl.honestit.spring.demo.config;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
13 | import org.springframework.security.crypto.password.PasswordEncoder;
14 |
15 | import javax.sql.DataSource;
16 |
17 | @Configuration
18 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
19 |
20 | private final DataSource dataSource;
21 |
22 | @Autowired
23 | public SecurityConfiguration(DataSource dataSource) {
24 | this.dataSource = dataSource;
25 | }
26 |
27 | @Bean
28 | public PasswordEncoder passwordEncoder() {
29 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
30 | }
31 |
32 | @Override
33 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
34 | auth.jdbcAuthentication()
35 | .dataSource(dataSource)
36 | .passwordEncoder(passwordEncoder())
37 | .usersByUsernameQuery("SELECT username, password, active FROM users WHERE username = ?")
38 | .authoritiesByUsernameQuery("SELECT username, 'ROLE_USER' FROM users WHERE username = ?");
39 | }
40 |
41 | @Override
42 | protected void configure(HttpSecurity http) throws Exception {
43 | http
44 | .authorizeRequests()
45 | .antMatchers("/").permitAll() // Dodajemy stronę główną, aby mógł wejść na nią każdy
46 | .antMatchers("/register").anonymous()
47 | .antMatchers("/login").anonymous()
48 | .anyRequest().authenticated()
49 | .and()
50 | .formLogin()
51 | .loginPage("/login")
52 | .defaultSuccessUrl("/") // Usuwamy plik `index.html` i dajemy ścieżkę do kontrolera strony głównej
53 | .and()
54 | .logout()
55 | .logoutSuccessUrl("/"); // j.w.
56 | }
57 | }
58 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.7.md:
--------------------------------------------------------------------------------
1 | Rozszerzony kod strony głownej `home-page` o formularz dodawania nowego ogłoszenia. Zwróć uwagę, że cała sekcja dodawania nowego ogłoszenia została umieszczona wewnątrz tagów `` oraz że na formularz pojawił się tag ` `.
2 |
3 | ```jsp
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
5 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
6 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Dodaj ogłoszenie
24 |
25 |
26 |
27 |
51 |
52 |
53 |
54 |
55 |
Lista ogłoszeń
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | Lp.
64 | Tytuł
65 | Treść
66 | Autor
67 | Data dodania
68 |
69 |
70 |
71 | ${stat.count}
72 | ${advert.title}
73 | ${advert.description}
74 | ${advert.owner.username}
75 | ${advert.posted}
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.8.md:
--------------------------------------------------------------------------------
1 | Kod kontrolera `AdvertControler`. Zwróć uwagę, że w klasie użyliśmy mechanizmu _loggera_, do zalogowania informacji o zapisywanym ogłoszeniu oraz o już zapisanym ogłoszeniu (zapisane będzie miało pole `id`). W aplikacji typu `Spring Boot` mamy bez dodawania zależności dostęp do wielu bibliotek logowania. My skorzystaliśmy z klasy `Logger` i klasy `LoggerFactory` z biblioteki `SLF4J`.
2 |
3 | ```java
4 | package pl.honestit.spring.demo.controllers;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestParam;
11 | import pl.honestit.spring.demo.model.domain.Advert;
12 | import pl.honestit.spring.demo.model.domain.User;
13 | import pl.honestit.spring.demo.model.repositories.AdvertRepository;
14 | import pl.honestit.spring.demo.model.repositories.UserRepository;
15 |
16 | import java.security.Principal;
17 |
18 | @Controller
19 | public class AdvertController {
20 |
21 | private static final Logger log = LoggerFactory.getLogger(AdvertController.class);
22 |
23 | private final UserRepository userRepository;
24 | private final AdvertRepository advertRepository;
25 |
26 | public AdvertController(UserRepository userRepository, AdvertRepository advertRepository) {
27 | this.userRepository = userRepository;
28 | this.advertRepository = advertRepository;
29 | }
30 |
31 | @PostMapping("/add-advert")
32 | public String processAddAdvert(String title, String description, Principal principal) {
33 | String username = principal.getName();
34 | User user = userRepository.findByUsername(username);
35 |
36 | Advert advert = new Advert();
37 | advert.setTitle(title);
38 | advert.setDescription(description);
39 | advert.setOwner(user);
40 |
41 | log.info("Próba zapisu ogłoszenia: " + advert);
42 | advert = advertRepository.save(advert);
43 | log.info("Zapisano ogłoszenie: " + advert);
44 |
45 | return "redirect:/";
46 | }
47 | }
48 | ```
49 |
50 | ---
51 |
52 | Rozszerzony interfejs `UserRepository` o nową metodę do wyszukiwania użytkownika:
53 |
54 | ```java
55 | package pl.honestit.spring.demo.model.repositories;
56 |
57 | import org.springframework.data.jpa.repository.JpaRepository;
58 | import pl.honestit.spring.demo.model.domain.User;
59 |
60 | import java.util.List;
61 |
62 | public interface UserRepository extends JpaRepository {
63 |
64 | User findByUsername(String username);
65 |
66 | List findAllByUsername(String username);
67 | }
68 | ```
--------------------------------------------------------------------------------
/module_3/resolutions/3.9.md:
--------------------------------------------------------------------------------
1 | Strona z menu głównym `main-menu.jsp`:
2 |
3 | ```jsp
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
5 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
6 |
7 |
8 | Honest IT
9 |
10 |
11 |
12 | Strona główna
14 |
15 |
16 | <%-- Sekcje główne menu dostępne tylko dla zalogowanych użytkowników --%>
17 |
18 |
19 |
20 |
21 | Witaj, nieznajomy
22 |
23 | Zaloguj
24 |
25 |
26 |
27 |
28 | Witaj, ${pageContext.request.userPrincipal.principal.username}
29 |
30 | Wyloguj
31 |
32 |
33 |
34 |
35 | Zarejestruj
36 |
37 |
38 |
39 | ```
40 |
41 | Zmodyfikowana strona `home-page` z uwzględnieniem menu:
42 |
43 | ```jsp
44 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
45 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
46 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
Dodaj ogłoszenie
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Tytuł ogłoszenia:
74 |
76 |
77 |
78 | Opis ogłoszenia
79 |
82 |
83 | Dodaj
84 | Wyczyść dane
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
Lista ogłoszeń
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | Lp.
103 | Tytuł
104 | Treść
105 | Autor
106 | Data dodania
107 |
108 |
109 |
110 | ${stat.count}
111 | ${advert.title}
112 | ${advert.description}
113 | ${advert.owner.username}
114 | ${advert.posted}
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | ```
125 |
126 | ---
127 |
128 | Zmodyfikowana strona `registration-form` z uwzględnieniem menu:
129 |
130 | ```jsp
131 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
132 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
Rejestracja
148 |
149 |
150 |
181 |
182 |
183 |
184 | ```
185 |
186 | ---
187 |
188 | Zmodyfikowana strona `login-page` z uwzględnieniem menu:
189 |
190 | ```jsp
191 | <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
192 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
193 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
Logowanie
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | Błędne dane logowania!
218 |
219 | ×
220 |
221 |
222 |
223 |
224 |
225 | Nazwa użytkownika
226 |
227 |
228 |
229 | Hasło
230 |
231 |
232 | Zaloguj
233 | Wyczyść dane
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | ```
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import java.net.*;
17 | import java.io.*;
18 | import java.nio.channels.*;
19 | import java.util.Properties;
20 |
21 | public class MavenWrapperDownloader {
22 |
23 | private static final String WRAPPER_VERSION = "0.5.6";
24 | /**
25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
26 | */
27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
29 |
30 | /**
31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
32 | * use instead of the default one.
33 | */
34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
35 | ".mvn/wrapper/maven-wrapper.properties";
36 |
37 | /**
38 | * Path where the maven-wrapper.jar will be saved to.
39 | */
40 | private static final String MAVEN_WRAPPER_JAR_PATH =
41 | ".mvn/wrapper/maven-wrapper.jar";
42 |
43 | /**
44 | * Name of the property which should be used to override the default download url for the wrapper.
45 | */
46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
47 |
48 | public static void main(String args[]) {
49 | System.out.println("- Downloader started");
50 | File baseDirectory = new File(args[0]);
51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
52 |
53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
54 | // wrapperUrl parameter.
55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
56 | String url = DEFAULT_DOWNLOAD_URL;
57 | if(mavenWrapperPropertyFile.exists()) {
58 | FileInputStream mavenWrapperPropertyFileInputStream = null;
59 | try {
60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
61 | Properties mavenWrapperProperties = new Properties();
62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
64 | } catch (IOException e) {
65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
66 | } finally {
67 | try {
68 | if(mavenWrapperPropertyFileInputStream != null) {
69 | mavenWrapperPropertyFileInputStream.close();
70 | }
71 | } catch (IOException e) {
72 | // Ignore ...
73 | }
74 | }
75 | }
76 | System.out.println("- Downloading from: " + url);
77 |
78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
79 | if(!outputFile.getParentFile().exists()) {
80 | if(!outputFile.getParentFile().mkdirs()) {
81 | System.out.println(
82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
83 | }
84 | }
85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
86 | try {
87 | downloadFileFromURL(url, outputFile);
88 | System.out.println("Done");
89 | System.exit(0);
90 | } catch (Throwable e) {
91 | System.out.println("- Error downloading");
92 | e.printStackTrace();
93 | System.exit(1);
94 | }
95 | }
96 |
97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception {
98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
99 | String username = System.getenv("MVNW_USERNAME");
100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
101 | Authenticator.setDefault(new Authenticator() {
102 | @Override
103 | protected PasswordAuthentication getPasswordAuthentication() {
104 | return new PasswordAuthentication(username, password);
105 | }
106 | });
107 | }
108 | URL website = new URL(urlString);
109 | ReadableByteChannel rbc;
110 | rbc = Channels.newChannel(website.openStream());
111 | FileOutputStream fos = new FileOutputStream(destination);
112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
113 | fos.close();
114 | rbc.close();
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/honestit/spring-intro/bf1bb64aacf7633d4705c6aae0cc2fd8d76352ee/projects/honestit-2020-10-11/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Mingw, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | fi
118 |
119 | if [ -z "$JAVA_HOME" ]; then
120 | javaExecutable="`which javac`"
121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
122 | # readlink(1) is not available as standard on Solaris 10.
123 | readLink=`which readlink`
124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
125 | if $darwin ; then
126 | javaHome="`dirname \"$javaExecutable\"`"
127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
128 | else
129 | javaExecutable="`readlink -f \"$javaExecutable\"`"
130 | fi
131 | javaHome="`dirname \"$javaExecutable\"`"
132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
133 | JAVA_HOME="$javaHome"
134 | export JAVA_HOME
135 | fi
136 | fi
137 | fi
138 |
139 | if [ -z "$JAVACMD" ] ; then
140 | if [ -n "$JAVA_HOME" ] ; then
141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
142 | # IBM's JDK on AIX uses strange locations for the executables
143 | JAVACMD="$JAVA_HOME/jre/sh/java"
144 | else
145 | JAVACMD="$JAVA_HOME/bin/java"
146 | fi
147 | else
148 | JAVACMD="`which java`"
149 | fi
150 | fi
151 |
152 | if [ ! -x "$JAVACMD" ] ; then
153 | echo "Error: JAVA_HOME is not defined correctly." >&2
154 | echo " We cannot execute $JAVACMD" >&2
155 | exit 1
156 | fi
157 |
158 | if [ -z "$JAVA_HOME" ] ; then
159 | echo "Warning: JAVA_HOME environment variable is not set."
160 | fi
161 |
162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
163 |
164 | # traverses directory structure from process work directory to filesystem root
165 | # first directory with .mvn subdirectory is considered project base directory
166 | find_maven_basedir() {
167 |
168 | if [ -z "$1" ]
169 | then
170 | echo "Path not specified to find_maven_basedir"
171 | return 1
172 | fi
173 |
174 | basedir="$1"
175 | wdir="$1"
176 | while [ "$wdir" != '/' ] ; do
177 | if [ -d "$wdir"/.mvn ] ; then
178 | basedir=$wdir
179 | break
180 | fi
181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
182 | if [ -d "${wdir}" ]; then
183 | wdir=`cd "$wdir/.."; pwd`
184 | fi
185 | # end of workaround
186 | done
187 | echo "${basedir}"
188 | }
189 |
190 | # concatenates all lines of a file
191 | concat_lines() {
192 | if [ -f "$1" ]; then
193 | echo "$(tr -s '\n' ' ' < "$1")"
194 | fi
195 | }
196 |
197 | BASE_DIR=`find_maven_basedir "$(pwd)"`
198 | if [ -z "$BASE_DIR" ]; then
199 | exit 1;
200 | fi
201 |
202 | ##########################################################################################
203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
204 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
205 | ##########################################################################################
206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
207 | if [ "$MVNW_VERBOSE" = true ]; then
208 | echo "Found .mvn/wrapper/maven-wrapper.jar"
209 | fi
210 | else
211 | if [ "$MVNW_VERBOSE" = true ]; then
212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
213 | fi
214 | if [ -n "$MVNW_REPOURL" ]; then
215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
216 | else
217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
218 | fi
219 | while IFS="=" read key value; do
220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
221 | esac
222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
223 | if [ "$MVNW_VERBOSE" = true ]; then
224 | echo "Downloading from: $jarUrl"
225 | fi
226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
227 | if $cygwin; then
228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
229 | fi
230 |
231 | if command -v wget > /dev/null; then
232 | if [ "$MVNW_VERBOSE" = true ]; then
233 | echo "Found wget ... using wget"
234 | fi
235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
236 | wget "$jarUrl" -O "$wrapperJarPath"
237 | else
238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
239 | fi
240 | elif command -v curl > /dev/null; then
241 | if [ "$MVNW_VERBOSE" = true ]; then
242 | echo "Found curl ... using curl"
243 | fi
244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
245 | curl -o "$wrapperJarPath" "$jarUrl" -f
246 | else
247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
248 | fi
249 |
250 | else
251 | if [ "$MVNW_VERBOSE" = true ]; then
252 | echo "Falling back to using Java to download"
253 | fi
254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
255 | # For Cygwin, switch paths to Windows format before running javac
256 | if $cygwin; then
257 | javaClass=`cygpath --path --windows "$javaClass"`
258 | fi
259 | if [ -e "$javaClass" ]; then
260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
261 | if [ "$MVNW_VERBOSE" = true ]; then
262 | echo " - Compiling MavenWrapperDownloader.java ..."
263 | fi
264 | # Compiling the Java class
265 | ("$JAVA_HOME/bin/javac" "$javaClass")
266 | fi
267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
268 | # Running the downloader
269 | if [ "$MVNW_VERBOSE" = true ]; then
270 | echo " - Running MavenWrapperDownloader.java ..."
271 | fi
272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
273 | fi
274 | fi
275 | fi
276 | fi
277 | ##########################################################################################
278 | # End of extension
279 | ##########################################################################################
280 |
281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
282 | if [ "$MVNW_VERBOSE" = true ]; then
283 | echo $MAVEN_PROJECTBASEDIR
284 | fi
285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
286 |
287 | # For Cygwin, switch paths to Windows format before running java
288 | if $cygwin; then
289 | [ -n "$M2_HOME" ] &&
290 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
291 | [ -n "$JAVA_HOME" ] &&
292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
293 | [ -n "$CLASSPATH" ] &&
294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
295 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
297 | fi
298 |
299 | # Provide a "standardized" way to retrieve the CLI args that will
300 | # work with both Windows and non-Windows executions.
301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
302 | export MAVEN_CMD_LINE_ARGS
303 |
304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
305 |
306 | exec "$JAVACMD" \
307 | $MAVEN_OPTS \
308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
311 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
124 |
125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
162 | if ERRORLEVEL 1 goto error
163 | goto end
164 |
165 | :error
166 | set ERROR_CODE=1
167 |
168 | :end
169 | @endlocal & set ERROR_CODE=%ERROR_CODE%
170 |
171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
175 | :skipRcPost
176 |
177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
179 |
180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
181 |
182 | exit /B %ERROR_CODE%
183 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.4.RELEASE
9 |
10 |
11 | pl.sda.projects
12 | adverts
13 | 0.0.1-SNAPSHOT
14 | adverts
15 | Cool app for adverts
16 |
17 |
18 | 11
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-security
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-thymeleaf
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-web
37 |
38 |
39 |
40 | com.h2database
41 | h2
42 | runtime
43 |
44 |
45 | org.projectlombok
46 | lombok
47 | true
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-starter-test
52 | test
53 |
54 |
55 | org.junit.vintage
56 | junit-vintage-engine
57 |
58 |
59 |
60 |
61 | org.springframework.security
62 | spring-security-test
63 | test
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.springframework.boot
71 | spring-boot-maven-plugin
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/AdvertsApplication.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.ComponentScan;
6 |
7 | @SpringBootApplication
8 | public class AdvertsApplication {
9 |
10 | public static void main(String[] args) {
11 | SpringApplication.run(AdvertsApplication.class, args);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/config/SecurityConfig.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.config;
2 |
3 |
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 | import org.springframework.security.config.annotation.web.builders.WebSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
11 | import org.springframework.security.crypto.password.PasswordEncoder;
12 |
13 | import javax.sql.DataSource;
14 |
15 | @Configuration
16 | public class SecurityConfig extends WebSecurityConfigurerAdapter {
17 |
18 | private DataSource dataSource;
19 |
20 | public SecurityConfig(DataSource dataSource) {
21 | this.dataSource = dataSource;
22 | }
23 |
24 | @Bean
25 | public PasswordEncoder passwordEncoder() {
26 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
27 | }
28 |
29 | @Override
30 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
31 | auth
32 | .jdbcAuthentication()
33 | .dataSource(dataSource)
34 | .passwordEncoder(passwordEncoder())
35 | .usersByUsernameQuery(
36 | "SELECT username, password, active FROM users WHERE username = ?")
37 | .authoritiesByUsernameQuery(
38 | "SELECT username, 'ROLE_USER' FROM users WHERE username = ?");
39 | }
40 |
41 | @Override
42 | public void configure(WebSecurity web) throws Exception {
43 | web
44 | .ignoring()
45 | .antMatchers("/h2-console", "/h2-console/**");
46 | }
47 |
48 | @Override
49 | protected void configure(HttpSecurity http) throws Exception {
50 | http
51 | .authorizeRequests()
52 | .antMatchers("/register").permitAll()
53 | .antMatchers("/login").permitAll()
54 | .anyRequest().authenticated()
55 | .and()
56 | .formLogin()
57 | .defaultSuccessUrl("/")
58 | .and()
59 | .logout()
60 | .logoutSuccessUrl("/login");
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/config/StartupDataLoader.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.config;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.context.event.ContextRefreshedEvent;
6 | import org.springframework.context.event.EventListener;
7 | import org.springframework.security.crypto.password.PasswordEncoder;
8 | import org.springframework.stereotype.Component;
9 | import pl.sda.projects.adverts.model.domain.Advert;
10 | import pl.sda.projects.adverts.model.domain.User;
11 | import pl.sda.projects.adverts.model.repository.AdvertRepository;
12 | import pl.sda.projects.adverts.model.repository.UserRepository;
13 |
14 | import java.time.LocalDateTime;
15 |
16 | @Component @Slf4j @RequiredArgsConstructor
17 | public class StartupDataLoader {
18 |
19 | // Mamy wygenerowany konstruktor dla wszystkich
20 | // pól typu final przez lomboka (@RequiredArgsConstructor)
21 | // więc nie tworzymy własnego, a jak mamy
22 | // tylko jeden, to Spring automatycznie (magicznie)
23 | // używa go do wstrzykiwania zależności
24 | private final UserRepository userRepository;
25 | private final AdvertRepository advertRepository;
26 | private final PasswordEncoder passwordEncoder;
27 |
28 | @EventListener
29 | public void onStartupPrepareData(ContextRefreshedEvent event) {
30 | log.info("Loading startup data...");
31 | userRepository.save(User.builder()
32 | .firstName("Dupa")
33 | .lastName("Dupa")
34 | .username("andrzej")
35 | .password(passwordEncoder.encode("andrzej"))
36 | .active(true)
37 | .build());
38 |
39 | User andrzej = userRepository.getByUsername("andrzej");
40 | advertRepository.save(Advert.builder()
41 | .title("Kupię psa")
42 | .description("Kupię ładnego, spokojnego psa")
43 | .user(andrzej)
44 | .posted(LocalDateTime.now())
45 | .build());
46 | advertRepository.save(Advert.builder()
47 | .title("Oddam mieszkanie")
48 | .description("Oddam mieszkanie w centrum")
49 | .user(andrzej)
50 | .posted(LocalDateTime.now().minusDays(1))
51 | .build());
52 | advertRepository.save(Advert.builder()
53 | .title("Zjem drzewo")
54 | .description("Zjem dowolne drzewo do 2m średnicy!")
55 | .user(andrzej)
56 | .posted(LocalDateTime.now().minusDays(1).minusHours(4))
57 | .build());
58 | log.info("Startup data loaded");
59 | }
60 |
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/controller/HomePageController.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.controller;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.security.core.context.SecurityContextHolder;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestParam;
12 | import pl.sda.projects.adverts.model.domain.Advert;
13 | import pl.sda.projects.adverts.model.domain.User;
14 | import pl.sda.projects.adverts.model.repository.AdvertRepository;
15 | import pl.sda.projects.adverts.model.repository.UserRepository;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.time.LocalDateTime;
19 |
20 | @Controller
21 | @RequestMapping("/")
22 | @Slf4j @RequiredArgsConstructor
23 | public class HomePageController {
24 |
25 | private final AdvertRepository advertRepository;
26 | private final UserRepository userRepository;
27 |
28 | @GetMapping
29 | public String prepareHomePage(Model model) {
30 | model.addAttribute("advertToAdd", Advert.builder().build());
31 | model.addAttribute("adverts", advertRepository.findAllByOrderByPostedDesc());
32 | return "home";
33 | }
34 |
35 | @PostMapping("/add-advert")
36 | public String processAddAdvert(@RequestParam String title,
37 | @RequestParam String description) {
38 |
39 | String username = SecurityContextHolder.getContext().getAuthentication().getName();
40 | User currentUser = userRepository.getByUsername(username);
41 | Advert advertToSave = Advert.builder()
42 | .title(title)
43 | .description(description)
44 | .posted(LocalDateTime.now())
45 | .user(currentUser)
46 | .build();
47 | log.debug("Advert to save: {}", advertToSave);
48 | advertRepository.save(advertToSave);
49 | log.debug("Saved advert: {}", advertToSave);
50 | return "redirect:/";
51 | }
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/controller/RegistrationController.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.controller;
2 |
3 |
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.security.crypto.password.PasswordEncoder;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.ui.Model;
9 | import org.springframework.ui.ModelMap;
10 | import org.springframework.web.bind.annotation.GetMapping;
11 | import org.springframework.web.bind.annotation.PostMapping;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RequestParam;
14 | import pl.sda.projects.adverts.model.domain.User;
15 | import pl.sda.projects.adverts.model.repository.UserRepository;
16 |
17 | @Controller @Slf4j
18 | @RequestMapping("/register")
19 | public class RegistrationController {
20 |
21 | private UserRepository userRepository;
22 | private PasswordEncoder passwordEncoder;
23 |
24 | @Autowired // userRepostiory będzie wstrzyknięte teraz przez Springa, hahahaha!!!
25 | public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
26 | this.userRepository = userRepository;
27 | this.passwordEncoder = passwordEncoder;
28 | }
29 |
30 | @GetMapping
31 | public String prepareRegistrationPage(Model model) {
32 | model.addAttribute("greetings", "Hello, Spring!");
33 | return "registration/registration-form";
34 | }
35 |
36 | @PostMapping
37 | public String processRegistrationData(@RequestParam String username,
38 | @RequestParam String password,
39 | @RequestParam String firstName,
40 | @RequestParam String lastName,
41 | ModelMap model) {
42 | User user = User.builder()
43 | .username(username)
44 | .password(passwordEncoder.encode(password))
45 | .firstName(firstName)
46 | .lastName(lastName)
47 | .active(true)
48 | .build();
49 |
50 | log.debug("User to save: {}", user);
51 | userRepository.save(user);
52 | log.info("New user saved: {}", user);
53 |
54 | model.addAttribute("savedUser", user);
55 | return "registration/registration-summary";
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/model/domain/Advert.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.model.domain;
2 |
3 | import lombok.*;
4 | import org.hibernate.annotations.ColumnDefault;
5 |
6 | import javax.persistence.*;
7 | import java.time.LocalDateTime;
8 | import java.time.format.DateTimeFormatter;
9 |
10 | @Entity @Table(name = "adverts")
11 | @Getter @Setter @ToString(exclude = "user") @EqualsAndHashCode(of = "id")
12 | @NoArgsConstructor @AllArgsConstructor @Builder
13 | public class Advert {
14 |
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Long id;
18 |
19 | @Column(nullable = false)
20 | private String title;
21 |
22 | @Column(columnDefinition = "TEXT")
23 | private String description;
24 |
25 | @Column(nullable = false)
26 | @ColumnDefault("now()")
27 | private LocalDateTime posted;
28 |
29 | @ManyToOne(optional = false)
30 | @JoinColumn(name = "user_id")
31 | private User user;
32 |
33 | @Column(name = "user_id", insertable = false, updatable = false)
34 | private Long userId;
35 |
36 | public String getPostedFormatted() {
37 | return posted.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/model/domain/User.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.model.domain;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 |
7 | @Entity
8 | // Spring Boot konfiguruje własny mechanizm nazewniczy
9 | // który domyślnie nazwy tabel tworzy przez stworzenie
10 | // liczby mnogiej z nazwy klasy i wszystko małymi
11 | // literami
12 | @Table(name = "users")
13 | @Getter @Setter @ToString(exclude = "password") @EqualsAndHashCode(of = "id")
14 | @AllArgsConstructor @NoArgsConstructor @Builder
15 | public class User {
16 |
17 | @Id
18 | @GeneratedValue(strategy = GenerationType.IDENTITY)
19 | private Long id;
20 | @Column(nullable = false, unique = true)
21 | private String username;
22 | @Column(nullable = false)
23 | private String password;
24 | // Spring Boot konfiguruje własny mechanizm nazewniczy
25 | // który domyślnie zamienia camel case na uderscore
26 | // (_) cale i wszystko z małych liter
27 | @Column(name = "first_name")
28 | private String firstName;
29 | @Column(name = "last_name")
30 | private String lastName;
31 | private Boolean active = true;
32 | }
33 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/model/repository/AdvertRepository.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.model.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import pl.sda.projects.adverts.model.domain.Advert;
5 |
6 | import java.util.List;
7 |
8 | public interface AdvertRepository extends JpaRepository {
9 |
10 | List findAllByOrderByPostedDesc();
11 | }
12 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/java/pl/sda/projects/adverts/model/repository/UserRepository.java:
--------------------------------------------------------------------------------
1 | package pl.sda.projects.adverts.model.repository;
2 |
3 | import jdk.javadoc.doclet.Reporter;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.repository.Repository;
6 | import pl.sda.projects.adverts.model.domain.User;
7 |
8 | public interface UserRepository extends JpaRepository {
9 |
10 | boolean existsByUsername(String username);
11 |
12 | User getByUsername(String username);
13 | }
14 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.driver-class-name=org.h2.Driver
2 | spring.datasource.url=jdbc:h2:mem:advertsDB
3 | spring.datasource.username=root
4 | spring.datasource.password=pass
5 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
6 |
7 | spring.jpa.hibernate.ddl-auto=update
8 |
9 | # --- konfiguracja bazy h2 (dostęp z przeglądarki)
10 | spring.h2.console.enabled=true
11 | spring.h2.console.path=/h2-console
12 | spring.h2.console.settings.web-allow-others=true
13 |
14 |
15 | logging.level.sql=debug
16 | logging.level.root=info
17 | logging.level.pl.sda.projects.adverts=debug
18 |
19 | spring.security.user.name=user
20 | spring.security.user.password={noop}pass
21 |
22 | #server.port=9000
23 |
--------------------------------------------------------------------------------
/projects/honestit-2020-10-11/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
13 |
16 |
19 | Ogłoszenia
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Dodaj ogłoszenie
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Tytuł:
36 |
37 |
38 | Treść:
39 |
40 |
41 | Dodaj
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
Lista ogłoszeń
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | Lp.
59 | Tytuł
60 | Treść
61 | Autor
62 | Data dodania
63 |
64 |
65 | 1
66 | Tytuł
67 | Treść
68 | Username
69 | yyyy-MM-dd
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |