From 6de45026cb86d0c79be2303ed358ac1a5014aa1a Mon Sep 17 00:00:00 2001 From: rawfishthelgh Date: Wed, 13 Sep 2023 11:29:09 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B8=B0=EB=B0=98=20mvc=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=EC=9B=8C=ED=81=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/bind/annotation/RequestMethod.java | 24 ++++++++++++++- .../mvc/tobe/AnnotationHandlerMapping.java | 29 +++++++++++++++++-- .../servlet/mvc/tobe/HandlerExecution.java | 11 ++++++- .../tobe/AnnotationHandlerMappingTest.java | 4 ++- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/mvc/src/main/java/web/org/springframework/web/bind/annotation/RequestMethod.java b/mvc/src/main/java/web/org/springframework/web/bind/annotation/RequestMethod.java index 1dd958bd23..548e0cb5ab 100644 --- a/mvc/src/main/java/web/org/springframework/web/bind/annotation/RequestMethod.java +++ b/mvc/src/main/java/web/org/springframework/web/bind/annotation/RequestMethod.java @@ -1,5 +1,27 @@ package web.org.springframework.web.bind.annotation; +import java.util.Arrays; + public enum RequestMethod { - GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE + GET("GET"), + HEAD("HEAD"), + POST("POST"), + PUT("PUT"), + PATCH("PATCH"), + DELETE("DELETE"), + OPTIONS("OPTIONS"), + TRACE("TRACE"); + + private final String methodName; + + RequestMethod(String methodName) { + this.methodName = methodName; + } + + public static RequestMethod from(String methodName) { + return Arrays.stream(values()) + .filter(method -> method.methodName.equals(methodName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 메소드입니다")); + } } diff --git a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMapping.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMapping.java index a355218efa..51f63a5920 100644 --- a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMapping.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMapping.java @@ -1,11 +1,18 @@ package webmvc.org.springframework.web.servlet.mvc.tobe; +import context.org.springframework.stereotype.Controller; import jakarta.servlet.http.HttpServletRequest; +import org.reflections.Reflections; 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 java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.Set; public class AnnotationHandlerMapping { @@ -19,11 +26,29 @@ public AnnotationHandlerMapping(final Object... basePackage) { this.handlerExecutions = new HashMap<>(); } - public void initialize() { + public void initialize() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Reflections reflections = new Reflections(basePackage); + Set> controllers = reflections.getTypesAnnotatedWith(Controller.class); + for (Class controller : controllers) { + Method[] methods = controller.getDeclaredMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(RequestMapping.class)) { + RequestMapping annotation = method.getAnnotation(RequestMapping.class); + String url = annotation.value(); + for (RequestMethod requestMethod : annotation.method()) { + Object instance = controller.getDeclaredConstructor().newInstance(); + HandlerKey handlerKey = new HandlerKey(url, requestMethod); + HandlerExecution handlerExecution = new HandlerExecution(instance, method); + handlerExecutions.put(handlerKey, handlerExecution); + } + } + } + } log.info("Initialized AnnotationHandlerMapping!"); } public Object getHandler(final HttpServletRequest request) { - return null; + HandlerKey handlerKey = new HandlerKey(request.getRequestURI(), RequestMethod.from(request.getMethod())); + return handlerExecutions.get(handlerKey); } } diff --git a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/HandlerExecution.java b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/HandlerExecution.java index 37c583fbdf..db306db6a5 100644 --- a/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/HandlerExecution.java +++ b/mvc/src/main/java/webmvc/org/springframework/web/servlet/mvc/tobe/HandlerExecution.java @@ -4,9 +4,18 @@ import jakarta.servlet.http.HttpServletResponse; import webmvc.org.springframework.web.servlet.ModelAndView; +import java.lang.reflect.Method; + public class HandlerExecution { + private final Object controller; + private final Method method; + + public HandlerExecution(Object controller, Method method) { + this.controller = controller; + this.method = method; + } public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception { - return null; + return (ModelAndView) method.invoke(controller, request, response); } } diff --git a/mvc/src/test/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMappingTest.java b/mvc/src/test/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMappingTest.java index dcec215a3f..89056886c3 100644 --- a/mvc/src/test/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMappingTest.java +++ b/mvc/src/test/java/webmvc/org/springframework/web/servlet/mvc/tobe/AnnotationHandlerMappingTest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.lang.reflect.InvocationTargetException; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -14,7 +16,7 @@ class AnnotationHandlerMappingTest { private AnnotationHandlerMapping handlerMapping; @BeforeEach - void setUp() { + void setUp() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { handlerMapping = new AnnotationHandlerMapping("samples"); handlerMapping.initialize(); }