diff --git a/app/src/main/java/com/techcourse/DispatcherServletInitializer.java b/app/src/main/java/com/techcourse/DispatcherServletInitializer.java index 6e814cdd25..53fb9af5c8 100644 --- a/app/src/main/java/com/techcourse/DispatcherServletInitializer.java +++ b/app/src/main/java/com/techcourse/DispatcherServletInitializer.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import web.org.springframework.web.WebApplicationInitializer; +import webmvc.org.springframework.web.servlet.mvc.DispatcherServlet; /** * Base class for {@link WebApplicationInitializer} diff --git a/app/src/main/java/com/techcourse/ManualHandlerMapping.java b/app/src/main/java/com/techcourse/ManualHandlerMapping.java deleted file mode 100644 index 09b09e17bf..0000000000 --- a/app/src/main/java/com/techcourse/ManualHandlerMapping.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.techcourse; - -import com.techcourse.controller.*; -import jakarta.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import webmvc.org.springframework.web.servlet.mvc.HandlerMapping; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; -import com.techcourse.controller.ForwardController; - -import java.util.HashMap; -import java.util.Map; - -public class ManualHandlerMapping implements HandlerMapping { - - private static final Logger log = LoggerFactory.getLogger(ManualHandlerMapping.class); - - private static final Map controllers = new HashMap<>(); - - @Override - public void initialize() { - controllers.put("/", new ForwardController("/index.jsp")); - controllers.put("/login", new LoginController()); - controllers.put("/login/view", new LoginViewController()); - controllers.put("/logout", new LogoutController()); - controllers.put("/register/view", new RegisterViewController()); - controllers.put("/register", new RegisterController()); - - log.info("Initialized Handler Mapping!"); - controllers.keySet() - .forEach(path -> log.info("Path : {}, Controller : {}", path, controllers.get(path).getClass())); - } - - @Override - public Object getHandler(final HttpServletRequest request) { - String requestURI = request.getRequestURI(); - - return controllers.get(requestURI); - } -} diff --git a/app/src/main/java/com/techcourse/controller/ForwardController.java b/app/src/main/java/com/techcourse/controller/ForwardController.java index 5c5ded8203..04e7c1d3c4 100644 --- a/app/src/main/java/com/techcourse/controller/ForwardController.java +++ b/app/src/main/java/com/techcourse/controller/ForwardController.java @@ -1,21 +1,21 @@ package com.techcourse.controller; +import context.org.springframework.stereotype.Controller; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.util.Objects; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; +import web.org.springframework.web.bind.annotation.RequestMapping; +import web.org.springframework.web.bind.annotation.RequestMethod; +import webmvc.org.springframework.web.servlet.ModelAndView; +import webmvc.org.springframework.web.servlet.view.JspView; -public class ForwardController implements Controller { +@Controller +public class ForwardController { - private final String path; + private static final String INDEX = "/index.jsp"; - public ForwardController(final String path) { - this.path = Objects.requireNonNull(path); - } - - @Override - public String execute(final HttpServletRequest request, final HttpServletResponse response) { - return path; + @RequestMapping(value = "/", method = RequestMethod.GET) + public ModelAndView forward(final HttpServletRequest request, final HttpServletResponse response) { + return new ModelAndView(new JspView(INDEX)); } } diff --git a/app/src/main/java/com/techcourse/controller/LoginController.java b/app/src/main/java/com/techcourse/controller/LoginController.java index 1ad294e3f2..aaea7e4ec1 100644 --- a/app/src/main/java/com/techcourse/controller/LoginController.java +++ b/app/src/main/java/com/techcourse/controller/LoginController.java @@ -2,20 +2,38 @@ import com.techcourse.domain.User; import com.techcourse.repository.InMemoryUserRepository; +import context.org.springframework.stereotype.Controller; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; +import web.org.springframework.web.bind.annotation.RequestMapping; +import web.org.springframework.web.bind.annotation.RequestMethod; +import webmvc.org.springframework.web.servlet.ModelAndView; +import webmvc.org.springframework.web.servlet.view.JspView; -public class LoginController implements Controller { +@Controller +public class LoginController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); + private static final String REDIRECT_INDEX_JSP = "redirect:/index.jsp"; + private static final String REDIRECT_401_JSP = "redirect:/401.jsp"; + private static final String LOGIN_JSP = "/login.jsp"; - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) { + @RequestMapping(value = "/login/view", method = RequestMethod.GET) + public ModelAndView getLoginForm(final HttpServletRequest req, final HttpServletResponse res) { + return UserSession.getUserFrom(req.getSession()) + .map(user -> { + log.info("logged in {}", user.getAccount()); + return new ModelAndView(new JspView(REDIRECT_INDEX_JSP)); + }) + .orElse(new ModelAndView(new JspView(LOGIN_JSP))); + } + + @RequestMapping(value = "/login", method = RequestMethod.POST) + public ModelAndView login(final HttpServletRequest req, final HttpServletResponse res) { if (UserSession.isLoggedIn(req.getSession())) { - return "redirect:/index.jsp"; + return new ModelAndView(new JspView(REDIRECT_INDEX_JSP)); } return InMemoryUserRepository.findByAccount(req.getParameter("account")) @@ -23,15 +41,15 @@ public String execute(final HttpServletRequest req, final HttpServletResponse re log.info("User : {}", user); return login(req, user); }) - .orElse("redirect:/401.jsp"); + .orElse(new ModelAndView(new JspView(REDIRECT_401_JSP))); } - private String login(final HttpServletRequest request, final User user) { + private ModelAndView login(final HttpServletRequest request, final User user) { if (user.checkPassword(request.getParameter("password"))) { final var session = request.getSession(); session.setAttribute(UserSession.SESSION_KEY, user); - return "redirect:/index.jsp"; + return new ModelAndView(new JspView(REDIRECT_INDEX_JSP)); } - return "redirect:/401.jsp"; + return new ModelAndView(new JspView(REDIRECT_401_JSP)); } } diff --git a/app/src/main/java/com/techcourse/controller/LoginViewController.java b/app/src/main/java/com/techcourse/controller/LoginViewController.java deleted file mode 100644 index 1b23421ad0..0000000000 --- a/app/src/main/java/com/techcourse/controller/LoginViewController.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.techcourse.controller; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; - -public class LoginViewController implements Controller { - - private static final Logger log = LoggerFactory.getLogger(LoginViewController.class); - - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) { - return UserSession.getUserFrom(req.getSession()) - .map(user -> { - log.info("logged in {}", user.getAccount()); - return "redirect:/index.jsp"; - }) - .orElse("/login.jsp"); - } -} diff --git a/app/src/main/java/com/techcourse/controller/LogoutController.java b/app/src/main/java/com/techcourse/controller/LogoutController.java index aa6c45b816..eb1d58554b 100644 --- a/app/src/main/java/com/techcourse/controller/LogoutController.java +++ b/app/src/main/java/com/techcourse/controller/LogoutController.java @@ -1,15 +1,22 @@ package com.techcourse.controller; +import context.org.springframework.stereotype.Controller; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; +import web.org.springframework.web.bind.annotation.RequestMapping; +import web.org.springframework.web.bind.annotation.RequestMethod; +import webmvc.org.springframework.web.servlet.ModelAndView; +import webmvc.org.springframework.web.servlet.view.JspView; -public class LogoutController implements Controller { +@Controller +public class LogoutController { - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) { + public static final String REDIRECT_ROOT = "redirect:/"; + + @RequestMapping(value = "/logout", method = RequestMethod.GET) + public ModelAndView logout(final HttpServletRequest req, final HttpServletResponse res) { final var session = req.getSession(); session.removeAttribute(UserSession.SESSION_KEY); - return "redirect:/"; + return new ModelAndView(new JspView(REDIRECT_ROOT)); } } diff --git a/app/src/main/java/com/techcourse/controller/RegisterController.java b/app/src/main/java/com/techcourse/controller/RegisterController.java index 6908111d81..d3db8ed58e 100644 --- a/app/src/main/java/com/techcourse/controller/RegisterController.java +++ b/app/src/main/java/com/techcourse/controller/RegisterController.java @@ -2,20 +2,33 @@ import com.techcourse.domain.User; import com.techcourse.repository.InMemoryUserRepository; +import context.org.springframework.stereotype.Controller; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; +import web.org.springframework.web.bind.annotation.RequestMapping; +import web.org.springframework.web.bind.annotation.RequestMethod; +import webmvc.org.springframework.web.servlet.ModelAndView; +import webmvc.org.springframework.web.servlet.view.JspView; -public class RegisterController implements Controller { +@Controller +public class RegisterController { - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) { + public static final String REGISTER_JSP = "/register.jsp"; + private static final String REDIRECT_INDEX_JSP = "redirect:/index.jsp"; + + @RequestMapping(value = "/register/view", method = RequestMethod.GET) + public ModelAndView getRegisterForm(final HttpServletRequest req, final HttpServletResponse res) { + return new ModelAndView(new JspView(REGISTER_JSP)); + } + + @RequestMapping(value = "/register", method = RequestMethod.POST) + public ModelAndView register(final HttpServletRequest req, final HttpServletResponse res) { final var user = new User(2, req.getParameter("account"), req.getParameter("password"), req.getParameter("email")); InMemoryUserRepository.save(user); - return "redirect:/index.jsp"; + return new ModelAndView(new JspView(REDIRECT_INDEX_JSP)); } } diff --git a/app/src/main/java/com/techcourse/controller/RegisterViewController.java b/app/src/main/java/com/techcourse/controller/RegisterViewController.java deleted file mode 100644 index 5b06b74c5e..0000000000 --- a/app/src/main/java/com/techcourse/controller/RegisterViewController.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.techcourse.controller; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import webmvc.org.springframework.web.servlet.mvc.asis.Controller; - -public class RegisterViewController implements Controller { - - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) { - return "/register.jsp"; - } -} diff --git a/app/src/main/java/com/techcourse/controller/UserController.java b/app/src/main/java/com/techcourse/controller/UserController.java new file mode 100644 index 0000000000..c1361f487b --- /dev/null +++ b/app/src/main/java/com/techcourse/controller/UserController.java @@ -0,0 +1,32 @@ +package com.techcourse.controller; + +import com.techcourse.domain.User; +import com.techcourse.repository.InMemoryUserRepository; +import context.org.springframework.stereotype.Controller; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import web.org.springframework.web.bind.annotation.RequestMapping; +import web.org.springframework.web.bind.annotation.RequestMethod; +import webmvc.org.springframework.web.servlet.ModelAndView; +import webmvc.org.springframework.web.servlet.view.JsonView; + +@Controller +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + + @RequestMapping(value = "/api/user", method = RequestMethod.GET) + public ModelAndView show(HttpServletRequest request, HttpServletResponse response) { + final String account = request.getParameter("account"); + log.debug("user id : {}", account); + + final ModelAndView modelAndView = new ModelAndView(new JsonView()); + final User user = InMemoryUserRepository.findByAccount(account) + .orElseThrow(); + + modelAndView.addObject("user", user); + return modelAndView; + } +} diff --git a/app/src/main/java/com/techcourse/DispatcherServlet.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/DispatcherServlet.java similarity index 87% rename from app/src/main/java/com/techcourse/DispatcherServlet.java rename to mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/DispatcherServlet.java index b1de875485..ce9f2e9a90 100644 --- a/app/src/main/java/com/techcourse/DispatcherServlet.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/DispatcherServlet.java @@ -1,7 +1,7 @@ -package com.techcourse; +package webmvc.org.springframework.web.servlet.mvc; -import com.techcourse.exception.HandlerAdapterNotFoundException; -import com.techcourse.exception.HandlerNotFoundException; +import webmvc.org.springframework.web.servlet.mvc.exception.HandlerAdapterNotFoundException; +import webmvc.org.springframework.web.servlet.mvc.exception.HandlerNotFoundException; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -14,10 +14,7 @@ import org.slf4j.LoggerFactory; import webmvc.org.springframework.web.servlet.ModelAndView; import webmvc.org.springframework.web.servlet.View; -import webmvc.org.springframework.web.servlet.mvc.asis.ManualHandlerAdapter; import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerAdapter; -import webmvc.org.springframework.web.servlet.mvc.HandlerAdapter; -import webmvc.org.springframework.web.servlet.mvc.HandlerMapping; import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping; public class DispatcherServlet extends HttpServlet { @@ -29,11 +26,9 @@ public class DispatcherServlet extends HttpServlet { static { handlerMappings = new ArrayList<>(); - handlerMappings.add(new ManualHandlerMapping()); handlerMappings.add(new AnnotationHandlerMapping()); handlerAdapters = new ArrayList<>(); - handlerAdapters.add(new ManualHandlerAdapter()); handlerAdapters.add(new AnnotationHandlerAdapter()); } diff --git a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/Controller.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/Controller.java deleted file mode 100644 index 4cbf58dd9a..0000000000 --- a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/Controller.java +++ /dev/null @@ -1,8 +0,0 @@ -package webmvc.org.springframework.web.servlet.mvc.asis; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -public interface Controller { - String execute(final HttpServletRequest req, final HttpServletResponse res); -} diff --git a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/ManualHandlerAdapter.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/ManualHandlerAdapter.java deleted file mode 100644 index a849bcd419..0000000000 --- a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/asis/ManualHandlerAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -package webmvc.org.springframework.web.servlet.mvc.asis; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.util.Enumeration; -import webmvc.org.springframework.web.servlet.ModelAndView; -import webmvc.org.springframework.web.servlet.mvc.HandlerAdapter; -import webmvc.org.springframework.web.servlet.view.JspView; - -public class ManualHandlerAdapter implements HandlerAdapter { - - @Override - public boolean supports(final Object handler) { - return (handler instanceof Controller); - } - - @Override - public ModelAndView handle(final Object handler, final HttpServletRequest request, - final HttpServletResponse response) { - Controller controller = (Controller) handler; - String viewName = controller.execute(request, response); - - ModelAndView modelAndView = new ModelAndView(new JspView(viewName)); - Enumeration attributeNames = request.getAttributeNames(); - while (attributeNames.hasMoreElements()) { - String attributeName = attributeNames.nextElement(); - Object attributeValue = request.getAttribute(attributeName); - modelAndView.addObject(attributeName, attributeValue); - } - - return modelAndView; - } -} diff --git a/app/src/main/java/com/techcourse/exception/HandlerAdapterNotFoundException.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerAdapterNotFoundException.java similarity index 73% rename from app/src/main/java/com/techcourse/exception/HandlerAdapterNotFoundException.java rename to mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerAdapterNotFoundException.java index 3a7f9a7fa4..a4be372654 100644 --- a/app/src/main/java/com/techcourse/exception/HandlerAdapterNotFoundException.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerAdapterNotFoundException.java @@ -1,4 +1,4 @@ -package com.techcourse.exception; +package webmvc.org.springframework.web.servlet.mvc.exception; public class HandlerAdapterNotFoundException extends RuntimeException { diff --git a/app/src/main/java/com/techcourse/exception/HandlerNotFoundException.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerNotFoundException.java similarity index 71% rename from app/src/main/java/com/techcourse/exception/HandlerNotFoundException.java rename to mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerNotFoundException.java index c3b5cd0dd1..d2173f47bf 100644 --- a/app/src/main/java/com/techcourse/exception/HandlerNotFoundException.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/exception/HandlerNotFoundException.java @@ -1,4 +1,4 @@ -package com.techcourse.exception; +package webmvc.org.springframework.web.servlet.mvc.exception; public class HandlerNotFoundException extends RuntimeException { diff --git a/mvc/src/main/java/webmvc/org/springframework/web/servlet/view/JsonView.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/view/JsonView.java index b42c3466f0..27f3ca1af1 100644 --- a/mvc/src/main/java/webmvc/org/springframework/web/servlet/view/JsonView.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/view/JsonView.java @@ -1,14 +1,37 @@ package webmvc.org.springframework.web.servlet.view; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import webmvc.org.springframework.web.servlet.View; - +import java.io.IOException; +import java.io.PrintWriter; import java.util.Map; +import web.org.springframework.http.MediaType; +import webmvc.org.springframework.web.servlet.View; public class JsonView implements View { @Override - public void render(final Map model, final HttpServletRequest request, HttpServletResponse response) throws Exception { + public void render(final Map model, final HttpServletRequest request, HttpServletResponse response) + throws Exception { + String jsonBody = convertModelToJson(model); + + response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + response.setContentLength(jsonBody.length()); + + try (PrintWriter writer = response.getWriter()) { + writer.write(jsonBody); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String convertModelToJson(final Map model) throws JsonProcessingException { + if (model.size() == 1) { + return String.valueOf(model.values().iterator().next()); + } + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(model); } }