Skip to content

Commit

Permalink
패키지 위치 변경 및 코드 정리
Browse files Browse the repository at this point in the history
  • Loading branch information
kang-hyungu authored and thdwoqor committed Sep 16, 2023
1 parent 7aea419 commit 37e31ff
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 112 deletions.
43 changes: 24 additions & 19 deletions app/src/main/java/com/techcourse/DispatcherServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,46 @@
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
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.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerExecution;
import webmvc.org.springframework.web.servlet.view.JspView;

public class DispatcherServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
private static final String BASE_PACKAGE = "com.techcourse";

private AnnotationHandlerMapping annotationHandlerMapping;
private ManualHandlerMapping manualHandlerMapping;

public DispatcherServlet() {
}

@Override
public void init() {
try {
annotationHandlerMapping = new AnnotationHandlerMapping(BASE_PACKAGE);
} catch (Exception e) {
throw new RuntimeException(e);
}
annotationHandlerMapping.initialize();
manualHandlerMapping = new ManualHandlerMapping();
manualHandlerMapping.initialize();
}

@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException {
log.debug("Method : {}, Request URI : {}", request.getMethod(), request.getRequestURI());
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
final String requestURI = request.getRequestURI();
log.debug("Method : {}, Request URI : {}", request.getMethod(), requestURI);

try {
HandlerExecution handler = annotationHandlerMapping.getHandler(request);
ModelAndView handle = handler.handle(request, response);
View view = handle.getView();
view.render(handle.getModel(), request, response);
final var controller = manualHandlerMapping.getHandler(requestURI);
final var viewName = controller.execute(request, response);
move(viewName, request, response);
} catch (Throwable e) {
log.error("Exception : {}", e.getMessage(), e);
throw new ServletException(e.getMessage());
}
}

private void move(final String viewName, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
if (viewName.startsWith(JspView.REDIRECT_PREFIX)) {
response.sendRedirect(viewName.substring(JspView.REDIRECT_PREFIX.length()));
return;
}

final var requestDispatcher = request.getRequestDispatcher(viewName);
requestDispatcher.forward(request, response);
}
}
35 changes: 35 additions & 0 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.techcourse;

import com.techcourse.controller.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.ForwardController;

import java.util.HashMap;
import java.util.Map;

public class ManualHandlerMapping {

private static final Logger log = LoggerFactory.getLogger(ManualHandlerMapping.class);

private static final Map<String, Controller> controllers = new HashMap<>();

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()));
}

public Controller getHandler(final String requestURI) {
log.debug("Request Mapping Uri : {}", requestURI);
return controllers.get(requestURI);
}
}
15 changes: 3 additions & 12 deletions app/src/main/java/com/techcourse/TomcatStarter.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.techcourse;

import java.io.File;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.scan.StandardJarScanner;

import java.io.File;

public class TomcatStarter {

public static final String WEBAPP_DIR_LOCATION = "app/src/main/webapp/";
Expand All @@ -23,24 +24,14 @@ public TomcatStarter(final String webappDirLocation, final int port) {
tomcat.setConnector(createConnector(port));

final var docBase = new File(webappDirLocation).getAbsolutePath();
StandardContext context = (StandardContext) tomcat.addWebapp("", docBase);

// try-catch 로 감싸지 않으면 실행이 안된다.
try {
DispatcherServletInitializer dispatcherServletInitializer = new DispatcherServletInitializer();
dispatcherServletInitializer.onStartup(context.getServletContext());
} catch (Exception e) {
e.printStackTrace();
}

final var context = (StandardContext) tomcat.addWebapp("", docBase);
skipJarScan(context);
skipClearReferences(context);
}

public void start() {
try {
tomcat.start();

} catch (LifecycleException e) {
throw new UncheckedServletException(e);
}
Expand Down
42 changes: 11 additions & 31 deletions app/src/main/java/com/techcourse/controller/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,36 @@

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 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.JspView;

@Controller
public class LoginController {
public class LoginController implements Controller {

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";

@RequestMapping(value = "/login/view", method = RequestMethod.GET)
public ModelAndView display(HttpServletRequest req, 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(HttpServletRequest req, HttpServletResponse res) {
@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
if (UserSession.isLoggedIn(req.getSession())) {
return new ModelAndView(new JspView(REDIRECT_INDEX_JSP));
return "redirect:/index.jsp";
}

ModelAndView modelAndView = InMemoryUserRepository.findByAccount(req.getParameter("account"))
return InMemoryUserRepository.findByAccount(req.getParameter("account"))
.map(user -> {
log.info("User : {}", user);
return checkPassword(req, user);
return login(req, user);
})
.orElse(new ModelAndView(new JspView(REDIRECT_401_JSP)));
modelAndView.addObject("id", req.getAttribute("id"));
return modelAndView;
.orElse("redirect:/401.jsp");
}

private ModelAndView checkPassword(final HttpServletRequest request, final User user) {
private String 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 new ModelAndView(new JspView(REDIRECT_INDEX_JSP));
return "redirect:/index.jsp";
}
return new ModelAndView(new JspView(REDIRECT_401_JSP));
return "redirect:/401.jsp";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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) throws Exception {
return UserSession.getUserFrom(req.getSession())
.map(user -> {
log.info("logged in {}", user.getAccount());
return "redirect:/index.jsp";
})
.orElse("/login.jsp");
}
}
17 changes: 5 additions & 12 deletions app/src/main/java/com/techcourse/controller/LogoutController.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
package com.techcourse.controller;

import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

@Controller
public class LogoutController {
public class LogoutController implements Controller {

private static final String REDIRECT_INDEX_JSP = "redirect:/index.jsp";

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest req, HttpServletResponse res) {
@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
final var session = req.getSession();
session.removeAttribute(UserSession.SESSION_KEY);
return new ModelAndView(new JspView(REDIRECT_INDEX_JSP));
return "redirect:/";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,20 @@

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 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;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

@Controller
public class RegisterController {
public class RegisterController implements Controller {

private static final String REDIRECT_INDEX_JSP = "redirect:/index.jsp";

@RequestMapping(value = "/register/view", method = RequestMethod.GET)
public ModelAndView display(HttpServletRequest req, HttpServletResponse res) {
return new ModelAndView(new JspView("/register.jsp"));
}

@RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView register(HttpServletRequest req, HttpServletResponse res) {
final var user = new User(
@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
final var user = new User(2,
req.getParameter("account"),
req.getParameter("password"),
req.getParameter("email"));
InMemoryUserRepository.save(user);

return new ModelAndView(new JspView(REDIRECT_INDEX_JSP));
return "redirect:/index.jsp";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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) throws Exception {
return "/register.jsp";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,30 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.View;

import java.util.Map;

public class JspView implements View {

private static final Logger log = LoggerFactory.getLogger(JspView.class);

public static final String REDIRECT_PREFIX = "redirect:";
private final String viewName;

public JspView(final String viewName) {
this.viewName = viewName;
}

@Override
public void render(final Map<String, ?> model, final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
public void render(final Map<String, ?> model, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
// todo

model.keySet().forEach(key -> {
log.debug("attribute name : {}, value : {}", key, model.get(key));
request.setAttribute(key, model.get(key));
});

if (viewName.startsWith(JspView.REDIRECT_PREFIX)) {
response.sendRedirect(viewName.substring(JspView.REDIRECT_PREFIX.length()));
return;
}

final var requestDispatcher = request.getRequestDispatcher(viewName);
requestDispatcher.forward(request, response);
// todo
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
package webmvc.org.springframework.web.servlet.mvc.tobe;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import samples.TestController;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class AnnotationHandlerMappingTest {

private AnnotationHandlerMapping handlerMapping;

@BeforeEach
void setUp() throws Exception {
void setUp() {
handlerMapping = new AnnotationHandlerMapping("samples");
handlerMapping.initialize();
}
Expand Down

0 comments on commit 37e31ff

Please sign in to comment.