diff --git a/page-controller/README.md b/page-controller/README.md
new file mode 100644
index 000000000..6a0e35d1e
--- /dev/null
+++ b/page-controller/README.md
@@ -0,0 +1,162 @@
+---
+title: Page Controller
+categories: Structural
+language: en
+tags:
+- Decoupling
+---
+
+## Name / classification
+
+Page Controller
+
+## Intent
+
+It is an approach of one page leading to one logical file that handles actions or requests on a website.
+
+## Explanation
+
+Real-world example
+
+> In a shopping website, there is a signup page to register a user profile.
+> After finishing to signup, the signup page will be redirected to a user page to show the user's registered information.
+
+In plain words
+
+> Page controller manages HTTP requests and data in a specific page using MVC idea.
+> The idea is that one page contains one Controller that handles Model and View.
+
+**Programmatic Example**
+
+Here's Signup controller when a user signup their information for a website.
+
+```java
+@Slf4j
+@Controller
+@Component
+public class SignupController {
+ SignupView view = new SignupView();
+ /**
+ * Signup Controller can handle http request and decide which model and view use.
+ */
+ SignupController() {
+ }
+
+ /**
+ * Handle http GET request.
+ */
+ @GetMapping("/signup")
+ public String getSignup() {
+ return view.display();
+ }
+
+ /**
+ * Handle http POST request and access model and view.
+ */
+ @PostMapping("/signup")
+ public String create(SignupModel form, RedirectAttributes redirectAttributes) {
+ LOGGER.info(form.getName());
+ LOGGER.info(form.getEmail());
+ redirectAttributes.addAttribute("name", form.getName());
+ redirectAttributes.addAttribute("email", form.getEmail());
+ redirectAttributes.addFlashAttribute("userInfo", form);
+ return view.redirect(form);
+ }
+}
+```
+Here's Signup model and view that are handled by Signup controller.
+
+```java
+@Component
+@Getter
+@Setter
+public class SignupModel {
+ private String name;
+ private String email;
+ private String password;
+
+ public SignupModel() {
+ }
+}
+```
+
+```java
+@Slf4j
+public class SignupView {
+ public SignupView() {
+ }
+
+ public String display() {
+ LOGGER.info("display signup front page");
+ return "/signup";
+ }
+
+ /**
+ * redirect to user page.
+ */
+ public String redirect(SignupModel form) {
+ LOGGER.info("Redirect to user page with " + "name " + form.getName() + " email " + form.getEmail());
+ return "redirect:/user";
+ }
+}
+```
+
+Here's User Controller to handle Get request in a user page.
+
+```java
+@Slf4j
+@Controller
+public class UserController {
+ UserView view = new UserView();
+
+ public UserController() {}
+
+ /**
+ * Handle http GET request and access view and model.
+ */
+ @GetMapping("/user")
+ public String getUserPath(SignupModel form, Model model) {
+ model.addAttribute("name", form.getName());
+ model.addAttribute("email", form.getEmail());
+ return view.display(form);
+ }
+}
+```
+
+Here's User Model and View that are handled by User controller.
+```java
+@Getter
+@Setter
+public class UserModel {
+ private String name;
+ private String email;
+
+ public UserModel() {}
+}
+```
+
+```java
+@Slf4j
+public class UserView {
+ /**
+ * displaying command to generate html.
+ * @param user model content.
+ */
+ public String display(SignupModel user) {
+ LOGGER.info("display user html" + " name " + user.getName() + " email " + user.getEmail());
+ return "/user";
+ }
+}
+```
+
+## Class diagram
+
+
+## Applicability
+Use the Page Controller pattern when
+- you implement a site where most controller logic is simple
+- you implement a site where particular actions are handled with a particular server page
+
+## Credits
+- [Page Controller](https://www.martinfowler.com/eaaCatalog/pageController.html)
+- [Pattern of Enterprise Application Architecture](https://www.martinfowler.com/books/eaa.html)
\ No newline at end of file
diff --git a/page-controller/etc/page-controller.urm.png b/page-controller/etc/page-controller.urm.png
new file mode 100644
index 000000000..d46bb0187
Binary files /dev/null and b/page-controller/etc/page-controller.urm.png differ
diff --git a/page-controller/etc/page-controller.urm.puml b/page-controller/etc/page-controller.urm.puml
new file mode 100644
index 000000000..c152ee019
--- /dev/null
+++ b/page-controller/etc/page-controller.urm.puml
@@ -0,0 +1,59 @@
+@startuml
+package com.iluwatar.page.controller {
+ class App {
+ - LOGGER : Logger {static}
+ + App()
+ + main(args : String[]) {static}
+ }
+ class SignupController {
+ - LOGGER : Logger {static}
+ ~ view : SignupView
+ ~ SignupController()
+ + create(form : SignupModel, redirectAttributes : RedirectAttributes) : String
+ + getSignup() : String
+ }
+ class SignupModel {
+ - email : String
+ - name : String
+ - password : String
+ + SignupModel()
+ + SignupModel(name : String, email : String, password : String)
+ + getEmail() : String
+ + getName() : String
+ + getPassword() : String
+ + setEmail(email : String)
+ + setName(name : String)
+ + setPassword(password : String)
+ }
+ class SignupView {
+ - LOGGER : Logger {static}
+ + SignupView()
+ + display() : String
+ + redirect(form : SignupModel) : String
+ }
+ class UserController {
+ - LOGGER : Logger {static}
+ ~ view : UserView
+ + UserController()
+ + getUserPath(form : SignupModel, model : Model) : String
+ }
+ class UserModel {
+ - email : String
+ - name : String
+ + UserModel()
+ + getEmail() : String
+ + getName() : String
+ + setEmail(email : String)
+ + setName(name : String)
+ }
+ class UserView {
+ - LOGGER : Logger {static}
+ + UserView()
+ + display(user : SignupModel) : String
+ }
+}
+UserController --> "-view" UserView
+UserController --> "-model" UserModel
+SignupController --> "-view" SignupView
+SignupController --> "-model" SignupModel
+@enduml
\ No newline at end of file
diff --git a/page-controller/pom.xml b/page-controller/pom.xml
new file mode 100644
index 000000000..1e75f7f86
--- /dev/null
+++ b/page-controller/pom.xml
@@ -0,0 +1,101 @@
+
+
+
+ 4.0.0
+ page-controller
+
+ com.iluwatar
+ java-design-patterns
+ 1.26.0-SNAPSHOT
+
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ org.springframework
+ spring-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+
+
+ com.iluwatar.page.controller.App
+
+
+
+
+
+
+
+
+
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/App.java b/page-controller/src/main/java/com.iluwatar.page.controller/App.java
new file mode 100644
index 000000000..278c01396
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/App.java
@@ -0,0 +1,48 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Page Controller pattern is utilized when we want to simplify relationship in a dynamic website.
+ * It is an approach of one front page leading to one logical file that handles HTTP requests and actions.
+ * In this example, we build a website with signup page handling an input form with Signup Controller, Signup View, and Signup Model
+ * and after signup, it is redirected to a user page handling with User Controller, User View, and User Model.
+*/
+@Slf4j
+@SpringBootApplication
+public class App {
+ /**
+ * Program entry point.
+ *
+ * @param args command line args
+ */
+ public static void main(final String[] args) {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/SignupController.java b/page-controller/src/main/java/com.iluwatar.page.controller/SignupController.java
new file mode 100644
index 000000000..2efdc9ef1
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/SignupController.java
@@ -0,0 +1,68 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+/**
+ * Signup Controller.
+ */
+@Slf4j
+@Controller
+@Component
+public class SignupController {
+ SignupView view = new SignupView();
+ /**
+ * Signup Controller can handle http request and decide which model and view use.
+ */
+ SignupController() {
+ }
+
+ /**
+ * Handle http GET request.
+ */
+ @GetMapping("/signup")
+ public String getSignup() {
+ return view.display();
+ }
+
+ /**
+ * Handle http POST request and access model and view.
+ */
+ @PostMapping("/signup")
+ public String create(SignupModel form, RedirectAttributes redirectAttributes) {
+ LOGGER.info(form.getName());
+ LOGGER.info(form.getEmail());
+ redirectAttributes.addAttribute("name", form.getName());
+ redirectAttributes.addAttribute("email", form.getEmail());
+ redirectAttributes.addFlashAttribute("userInfo", form);
+ return view.redirect(form);
+ }
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/SignupModel.java b/page-controller/src/main/java/com.iluwatar.page.controller/SignupModel.java
new file mode 100644
index 000000000..97229c402
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/SignupModel.java
@@ -0,0 +1,44 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.stereotype.Component;
+
+/**
+ * ignup model.
+ */
+@Component
+@Getter
+@Setter
+public class SignupModel {
+ private String name;
+ private String email;
+ private String password;
+
+ public SignupModel() {
+ }
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/SignupView.java b/page-controller/src/main/java/com.iluwatar.page.controller/SignupView.java
new file mode 100644
index 000000000..5d127ea2a
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/SignupView.java
@@ -0,0 +1,49 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Signup View.
+ */
+@Slf4j
+public class SignupView {
+ public SignupView() {
+ }
+
+ public String display() {
+ LOGGER.info("display signup front page");
+ return "/signup";
+ }
+
+ /**
+ * redirect to user page.
+ */
+ public String redirect(SignupModel form) {
+ LOGGER.info("Redirect to user page with " + "name " + form.getName() + " email " + form.getEmail());
+ return "redirect:/user";
+ }
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/UserController.java b/page-controller/src/main/java/com.iluwatar.page.controller/UserController.java
new file mode 100644
index 000000000..e3bcca6f1
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/UserController.java
@@ -0,0 +1,51 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * User Controller.
+ */
+@Slf4j
+@Controller
+public class UserController {
+ private final UserView view = new UserView();
+
+ public UserController() {}
+
+ /**
+ * Handle http GET request and access view and model.
+ */
+ @GetMapping("/user")
+ public String getUserPath(SignupModel form, Model model) {
+ model.addAttribute("name", form.getName());
+ model.addAttribute("email", form.getEmail());
+ return view.display(form);
+ }
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/UserModel.java b/page-controller/src/main/java/com.iluwatar.page.controller/UserModel.java
new file mode 100644
index 000000000..86e9548a2
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/UserModel.java
@@ -0,0 +1,40 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * User model.
+ */
+@Getter
+@Setter
+public class UserModel {
+ private String name;
+ private String email;
+
+ public UserModel() {}
+}
diff --git a/page-controller/src/main/java/com.iluwatar.page.controller/UserView.java b/page-controller/src/main/java/com.iluwatar.page.controller/UserView.java
new file mode 100644
index 000000000..3f4469d7d
--- /dev/null
+++ b/page-controller/src/main/java/com.iluwatar.page.controller/UserView.java
@@ -0,0 +1,42 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * User view class generating html file.
+ */
+@Slf4j
+public class UserView {
+ /**
+ * displaying command to generate html.
+ * @param user model content.
+ */
+ public String display(SignupModel user) {
+ LOGGER.info("display user html" + " name " + user.getName() + " email " + user.getEmail());
+ return "/user";
+ }
+}
diff --git a/page-controller/src/main/resources/application.properties b/page-controller/src/main/resources/application.properties
new file mode 100644
index 000000000..59cc8812c
--- /dev/null
+++ b/page-controller/src/main/resources/application.properties
@@ -0,0 +1,25 @@
+#
+# The MIT License
+# Copyright © 2014-2021 Ilkka Seppälä
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+#spring.thymeleaf.mode=HTML
+
+server.port=51515
diff --git a/page-controller/src/main/resources/templates/signup.html b/page-controller/src/main/resources/templates/signup.html
new file mode 100644
index 000000000..56c5487fe
--- /dev/null
+++ b/page-controller/src/main/resources/templates/signup.html
@@ -0,0 +1,27 @@
+
+
+
+
+ Signup
+
+
+
+Sign Up
+
+
diff --git a/page-controller/src/main/resources/templates/user.html b/page-controller/src/main/resources/templates/user.html
new file mode 100644
index 000000000..70130cef6
--- /dev/null
+++ b/page-controller/src/main/resources/templates/user.html
@@ -0,0 +1,12 @@
+
+
+
+
+ User
+
+
+
+Your Information
+Name:
+Email:
+
\ No newline at end of file
diff --git a/page-controller/src/test/java/com/iluwatar/page/controller/AppTest.java b/page-controller/src/test/java/com/iluwatar/page/controller/AppTest.java
new file mode 100644
index 000000000..9dcbfe3f8
--- /dev/null
+++ b/page-controller/src/test/java/com/iluwatar/page/controller/AppTest.java
@@ -0,0 +1,38 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+/**
+ * Application test
+ */
+public class AppTest {
+ @Test
+ void shouldExecuteApplicationWithoutException() {
+ assertDoesNotThrow(() -> App.main(new String[]{}));
+ }
+}
diff --git a/page-controller/src/test/java/com/iluwatar/page/controller/SignupControllerTest.java b/page-controller/src/test/java/com/iluwatar/page/controller/SignupControllerTest.java
new file mode 100644
index 000000000..7260c24d4
--- /dev/null
+++ b/page-controller/src/test/java/com/iluwatar/page/controller/SignupControllerTest.java
@@ -0,0 +1,57 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Test for Signup Controller
+ */
+public class SignupControllerTest {
+
+ /**
+ * Verify if user can sign up and redirect to user page
+ */
+ @Test
+ void testSignup() {
+ var controller = new SignupController();
+ controller.getSignup();
+
+ RedirectAttributes redirectAttributes = new RedirectAttributesModelMap();
+ String redirectPath = controller.create(retrieveSignupData(), redirectAttributes);
+ assertEquals("redirect:/user", redirectPath);
+ }
+
+ public static SignupModel retrieveSignupData() {
+ SignupModel model = new SignupModel();
+ model.setName("Lily");
+ model.setEmail("lily@email.com");
+ model.setPassword("password1234");
+ return model;
+ }
+}
diff --git a/page-controller/src/test/java/com/iluwatar/page/controller/SignupModelTest.java b/page-controller/src/test/java/com/iluwatar/page/controller/SignupModelTest.java
new file mode 100644
index 000000000..46e60eb94
--- /dev/null
+++ b/page-controller/src/test/java/com/iluwatar/page/controller/SignupModelTest.java
@@ -0,0 +1,63 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.page.controller;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Test for Signup Model
+ */
+public class SignupModelTest {
+ /**
+ * Verify if a user can set a name properly
+ */
+ @Test
+ void testSetName() {
+ SignupModel model = new SignupModel();
+ model.setName("Lily");
+ assertEquals("Lily", model.getName());
+ }
+
+ /**
+ * Verify if a user can set an email properly
+ */
+ @Test
+ void testSetEmail() {
+ SignupModel model = new SignupModel();
+ model.setEmail("Lily@email");
+ assertEquals("Lily@email", model.getEmail());
+ }
+
+ /**
+ * Verify if a user can set a password properly
+ */
+ @Test
+ void testSetPassword() {
+ SignupModel model = new SignupModel();
+ model.setPassword("password1234");
+ assertEquals("password1234", model.getPassword());
+ }
+}
diff --git a/page-controller/src/test/java/com/iluwatar/page/controller/UserControllerTest.java b/page-controller/src/test/java/com/iluwatar/page/controller/UserControllerTest.java
new file mode 100644
index 000000000..d20d5e036
--- /dev/null
+++ b/page-controller/src/test/java/com/iluwatar/page/controller/UserControllerTest.java
@@ -0,0 +1,36 @@
+package com.iluwatar.page.controller;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+public class UserControllerTest {
+ private UserController userController;
+
+ @Autowired
+ MockMvc mockMvc;
+
+ /**
+ * Verify if view and model are directed properly
+ */
+ @Test
+ void testGetUserPath () throws Exception {
+ this.mockMvc.perform(get("/user")
+ .param("name", "Lily")
+ .param("email", "Lily@email.com"))
+ .andExpect(status().isOk())
+ .andExpect(model().attribute("name", "Lily"))
+ .andExpect(model().attribute("email", "Lily@email.com"))
+ .andReturn();
+ }
+}
diff --git a/page-controller/src/test/java/com/iluwatar/page/controller/UserModelTest.java b/page-controller/src/test/java/com/iluwatar/page/controller/UserModelTest.java
new file mode 100644
index 000000000..42e8e0c30
--- /dev/null
+++ b/page-controller/src/test/java/com/iluwatar/page/controller/UserModelTest.java
@@ -0,0 +1,27 @@
+package com.iluwatar.page.controller;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class UserModelTest {
+ /**
+ * Verify if a user can set a name properly
+ */
+ @Test
+ void testSetName() {
+ UserModel model = new UserModel();
+ model.setName("Lily");
+ assertEquals("Lily", model.getName());
+ }
+
+ /**
+ * Verify if a user can set an email properly
+ */
+ @Test
+ void testSetEmail() {
+ UserModel model = new UserModel();
+ model.setEmail("Lily@email");
+ assertEquals("Lily@email", model.getEmail());
+ }
+}