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