-
Notifications
You must be signed in to change notification settings - Fork 305
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단계] 베로(김은솔) 미션 제출합니다. #553
Merged
Merged
Changes from 8 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
4b9f9c8
refactor: 필드 타입을 배열로 변경
Cyma-s ed4da09
feat: JsonView, JspView 구현
Cyma-s 582e94f
refactor: 팩토리 클래스 삭제
Cyma-s 3c1dc7e
feat: ApplicationContext 로 의존관계 로드하도록 기능 추가
Cyma-s 7e0be5a
refactor: 레거시 코드 리팩토링
Cyma-s 3ecdc3b
refactor: 레거시 코드 리팩토링
Cyma-s 3f492b1
refactor: ViewResolver 삭제 및 레거시 컨트롤러 리팩터링
Cyma-s 6e34678
chore: 알맞는 패키지 이동
Cyma-s d8cd0e0
test: ApplicationContext 에서 빈을 가져오도록 변경
Cyma-s fd365ce
fix: 올바른 패키지로 이동
Cyma-s 9731d76
refactor: 사용하지 않는 메서드 삭제
Cyma-s d36fd8a
refactor: ObjectMapper 와 JsonView 통합
Cyma-s d3d65af
refactor: 생성자 파라미터 가변인자로 변경
Cyma-s File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
16 changes: 0 additions & 16 deletions
16
app/src/main/java/com/techcourse/HandlerAdapterFactory.java
This file was deleted.
Oops, something went wrong.
15 changes: 0 additions & 15 deletions
15
app/src/main/java/com/techcourse/HandlerMappingFactory.java
This file was deleted.
Oops, something went wrong.
42 changes: 0 additions & 42 deletions
42
app/src/main/java/com/techcourse/ManualHandlerMapping.java
This file was deleted.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
app/src/main/java/com/techcourse/controller/ForwardController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
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.view.ModelAndView; | ||
import webmvc.org.springframework.web.servlet.view.JspView; | ||
|
||
@Controller | ||
public class ForwardController { | ||
|
||
@RequestMapping(value = "/", method = RequestMethod.GET) | ||
public ModelAndView showIndex(final HttpServletRequest request, final HttpServletResponse response) { | ||
return new ModelAndView(new JspView("index.jsp")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 16 additions & 10 deletions
26
app/src/main/java/com/techcourse/controller/LoginViewController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,28 @@ | ||
package com.techcourse.controller; | ||
|
||
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.view.ModelAndView; | ||
import webmvc.org.springframework.web.servlet.view.JspView; | ||
import webmvc.org.springframework.web.servlet.view.RedirectView; | ||
|
||
public class LoginViewController implements Controller { | ||
@Controller | ||
public class LoginViewController { | ||
|
||
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"); | ||
@RequestMapping(value = "/login/view", method = RequestMethod.GET) | ||
public ModelAndView show(final HttpServletRequest request, final HttpServletResponse response) { | ||
return UserSession.getUserFrom(request.getSession()) | ||
.map(user -> { | ||
log.info("logged in {}", user.getAccount()); | ||
return new ModelAndView(new RedirectView("/index.jsp")); | ||
}) | ||
.orElse(new ModelAndView(new JspView("/login.jsp"))); | ||
} | ||
} |
17 changes: 11 additions & 6 deletions
17
app/src/main/java/com/techcourse/controller/LogoutController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,20 @@ | ||
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.view.ModelAndView; | ||
import webmvc.org.springframework.web.servlet.view.RedirectView; | ||
|
||
public class LogoutController implements Controller { | ||
@Controller | ||
public class LogoutController { | ||
|
||
@Override | ||
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception { | ||
final var session = req.getSession(); | ||
@RequestMapping(value = "/logout", method = RequestMethod.GET) | ||
public ModelAndView logout(final HttpServletRequest request, final HttpServletResponse response) { | ||
final var session = request.getSession(); | ||
session.removeAttribute(UserSession.SESSION_KEY); | ||
return "redirect:/"; | ||
return new ModelAndView(new RedirectView("/index.jsp")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 10 additions & 5 deletions
15
app/src/main/java/com/techcourse/controller/RegisterViewController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,18 @@ | ||
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.view.ModelAndView; | ||
import webmvc.org.springframework.web.servlet.view.JspView; | ||
|
||
public class RegisterViewController implements Controller { | ||
@Controller | ||
public class RegisterViewController { | ||
|
||
@Override | ||
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception { | ||
return "/register.jsp"; | ||
@RequestMapping(value = "/register/view", method = RequestMethod.GET) | ||
public ModelAndView show(final HttpServletRequest request, final HttpServletResponse response) { | ||
return new ModelAndView(new JspView("/register.jsp")); | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
mvc/src/main/java/context/org/springframework/context/ApplicationContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package context.org.springframework.context; | ||
|
||
import context.org.springframework.stereotype.Controller; | ||
import core.org.springframework.util.ReflectionUtils; | ||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Field; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import org.reflections.Reflections; | ||
import webmvc.org.springframework.web.servlet.mvc.handler.adapter.HandlerAdapter; | ||
import webmvc.org.springframework.web.servlet.mvc.handler.mapping.HandlerMapping; | ||
|
||
public class ApplicationContext { | ||
|
||
private static final String INTERNAL_BASE_PACKAGE = "webmvc.org.springframework.web.servlet"; | ||
private static final List<Class<?>> beanClasses = List.of( | ||
HandlerMapping.class, | ||
HandlerAdapter.class, | ||
ApplicationContextAware.class | ||
); | ||
private static final List<Class<? extends Annotation>> beanAnnotations = List.of( | ||
Controller.class | ||
); | ||
|
||
private final Map<Class<?>, Object> beans; | ||
|
||
public ApplicationContext(final String externalPackage) { | ||
this.beans = new HashMap<>(); | ||
registerBeans(INTERNAL_BASE_PACKAGE); | ||
registerBeans(externalPackage); | ||
initialize(); | ||
} | ||
|
||
public void registerBeans(final String basePackage) { | ||
final Reflections reflections = new Reflections(basePackage); | ||
beanClasses.stream() | ||
.map(reflections::getSubTypesOf) | ||
.forEach(this::registerBeans); | ||
beanAnnotations.stream() | ||
.map(reflections::getTypesAnnotatedWith) | ||
.forEach(this::registerBeans); | ||
} | ||
|
||
private <T> void registerBeans(final Set<Class<? extends T>> objectClasses) { | ||
objectClasses.stream() | ||
.filter(clazz -> !clazz.isInterface()) | ||
.forEach(this::registerBean); | ||
} | ||
|
||
private void registerBean(final Class<?> clazz) { | ||
try { | ||
final Constructor<?> constructor = ReflectionUtils.accessibleConstructor(clazz); | ||
final Object bean = constructor.newInstance(); | ||
beans.put(clazz, bean); | ||
} catch (NoSuchMethodException e) { | ||
throw new RuntimeException(clazz.getName() + " 기본 생성자가 존재하지 않습니다."); | ||
} catch (InvocationTargetException e) { | ||
throw new RuntimeException("기본 생성자를 호출할 수 없습니다."); | ||
} catch (InstantiationException e) { | ||
throw new RuntimeException("인스턴스를 생성할 수 없습니다."); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("기본 생성자에 접근할 수 없습니다."); | ||
} | ||
} | ||
|
||
public void initialize() { | ||
setFields(); | ||
setApplicationContext(); | ||
} | ||
|
||
private void setFields() { | ||
for (final Class<?> clazz : beans.keySet()) { | ||
final Field[] fields = clazz.getDeclaredFields(); | ||
for (final Field field : fields) { | ||
setField(clazz, field); | ||
} | ||
} | ||
} | ||
|
||
private void setField(final Class<?> clazz, final Field field) { | ||
final Class<?> type = field.getType(); | ||
final Object bean = getBean(type); | ||
if (bean != null) { | ||
try { | ||
field.setAccessible(true); | ||
field.set(beans.get(clazz), bean); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("필드에 접근할 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
public void setApplicationContext() { | ||
beans.values().stream() | ||
.filter(bean -> bean instanceof ApplicationContextAware) | ||
.forEach(bean -> ((ApplicationContextAware) bean).setApplicationContext(this)); | ||
} | ||
|
||
public Object getBean(final Class<?> classType) { | ||
return beans.get(classType); | ||
} | ||
|
||
public List<Object> getBeansOfAnnotationType(final Class<? extends Annotation> annotationType) { | ||
return beans.keySet().stream() | ||
.filter(clazz -> clazz.isAnnotationPresent(annotationType)) | ||
.map(beans::get) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public <T> List<? extends T> getBeansOfType(final Class<T> classType) { | ||
return beans.keySet().stream() | ||
.filter(classType::isAssignableFrom) | ||
.map(beans::get) | ||
.map(classType::cast) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public으로
registerBeans
메서드와initalilize
메서드를 열어두었더라고요!그래서인지 생성자의 파라미터를 가변인자로 받아도 좋을거같다는 생각이 들었네요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분은 내부 패키지와 외부 패키지를 분리하려고 가변 인자로 받지 않고 각각 받았습니다!
그런데 스프링 코드를 보니 실제로는 가변인자로 가져오고 있네요 🧐
AnnotationConfigServletWebApplicationContext
를 보면, scan 이라는 함수가 있습니다.이런 것처럼 basePackages 들을 가변인자로 받는 걸 보면, 가변 인자로 받아도 상관 없을 것 같네요!!