Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MVC 구현하기 - 3단계] 애쉬(정설희) 미션 제출합니다. #598

Merged
merged 12 commits into from
Sep 27, 2023
24 changes: 0 additions & 24 deletions app/src/main/java/com/techcourse/ControllerHandlerAdapter.java

This file was deleted.

61 changes: 0 additions & 61 deletions app/src/main/java/com/techcourse/DispatcherServlet.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.WebApplicationInitializer;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.DispatcherServlet;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerExecutionHandlerAdapter;

/**
* Base class for {@link WebApplicationInitializer}
* implementations that register a {@link DispatcherServlet} in the servlet context.
* Base class for {@link WebApplicationInitializer} implementations that register a {@link DispatcherServlet} in the
* servlet context.
*/
public class DispatcherServletInitializer implements WebApplicationInitializer {

Expand All @@ -18,11 +21,13 @@ public class DispatcherServletInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext servletContext) {
final var dispatcherServlet = new DispatcherServlet();

dispatcherServlet.addHandlerMapping(new AnnotationHandlerMapping(getClass().getPackage().getName()));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mvc 모듈에 있는 DispatcherServlet이 app 모듈에 있는 요소를 모르도록 신경써서 잘 구현해주신 것 같아요!!
저도 어떻게 Controller들이 구현된 패키지를 전달할지 고민했었는데 우연히AnnotationHandlerMapping에 아무 것도 넣지 않았는데도 작동하더라구요???Reflection의 생성자에 아무런 값도 전달되지 않았을 때 ClassLoader에서 읽어오는 방식인 것 같은데 신기했습니다

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 진짜 그렇네요... 너무 신기해요 ㅋㅋㅋ
덕분에 개념 하나 더 배워갔어요 감사해요 👍

dispatcherServlet.addHandlerAdapter(new HandlerExecutionHandlerAdapter());
dispatcherServlet.init();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 dispatcherServlet의 init()을 호출해주는데 Servlet Container(ex. tomcat)가 Servlet의 생성 주기를 관리하니까 호출해주지 않아도 되지 않을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇네요! DispatcherServlet도 Servlet이니 ServletContainer에서 생명주기를 관리하겠군요!!
꼼꼼하게 봐주셔서 감사합니다!!

final var registration = servletContext.addServlet(DEFAULT_SERVLET_NAME, dispatcherServlet);
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + DEFAULT_SERVLET_NAME + "'. " +
"Check if there is another servlet registered under the same name.");
"Check if there is another servlet registered under the same name.");
}

registration.setLoadOnStartup(1);
Expand Down
41 changes: 0 additions & 41 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java

This file was deleted.

40 changes: 30 additions & 10 deletions app/src/main/java/com/techcourse/controller/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,48 @@

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;

public class LoginController implements Controller {
@Controller
@RequestMapping("/login")
public class LoginController {

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

@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
@RequestMapping(method = RequestMethod.GET)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주어진 정적 파일에서 로그인 페이지를 얻는 HTTP 요청과 매핑이 안 되서 호출되지가 않아요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

직접 localhost:8080/login으로 접속해 테스트하고, 대시보드에 로그인/로그아웃 버튼이 있는걸 인지하지 못해서 해당 부분을 신경못썼네요 🥲
반영하겠습니다!!

public ModelAndView getLoginView(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
return UserSession.getUserFrom(req.getSession())
.map(user -> {
log.info("logged in {}", user.getAccount());
return convertToView("redirect:/index.jsp");
})
.orElse(convertToView("/login.jsp"));
}

private ModelAndView convertToView(String viewName) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 분리 좋아요👍👍

return new ModelAndView(new JspView(viewName));
}

@RequestMapping(method = RequestMethod.POST)
public ModelAndView login(final HttpServletRequest req, final HttpServletResponse res) {
if (UserSession.isLoggedIn(req.getSession())) {
return "redirect:/index.jsp";
return convertToView("redirect:/index.jsp");
}

return InMemoryUserRepository.findByAccount(req.getParameter("account"))
.map(user -> {
log.info("User : {}", user);
return login(req, user);
})
.orElse("redirect:/401.jsp");
.map(user -> {
log.info("User : {}", user);
return convertToView(login(req, user));
})
.orElse(convertToView("redirect:/401.jsp"));
}

private String login(final HttpServletRequest request, final User user) {
Expand Down

This file was deleted.

21 changes: 16 additions & 5 deletions app/src/main/java/com/techcourse/controller/LogoutController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
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
@RequestMapping("/logout")

@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
public class LogoutController {

@RequestMapping(method = RequestMethod.GET, value = "/view")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요것도 주어진 정적 파일에서 로그아웃 하는 HTTP 요청이랑 매핑이 안 되서 작동하지 않네요😅

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#598 (comment)

이 부분도 수정했습니다!!

public ModelAndView execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
final var session = req.getSession();
session.removeAttribute(UserSession.SESSION_KEY);
return "redirect:/";
return convertToView("redirect:/");
}

private ModelAndView convertToView(String viewName) {
return new ModelAndView(new JspView(viewName));
}
}
32 changes: 32 additions & 0 deletions app/src/main/java/com/techcourse/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,4 @@ public Map<String, Object> getModel() {
public View getView() {
return view;
}

public String getViewName() {
return view.getName();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package webmvc.org.springframework.web.servlet;

import java.util.Map;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;

public interface View {
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;

String getName();
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}

This file was deleted.

This file was deleted.

Loading
Loading