diff --git a/src/main/java/spring/mvc/handler/mapping/AnnotationHandlerMapping.java b/src/main/java/spring/mvc/handler/mapping/AnnotationHandlerMapping.java new file mode 100644 index 0000000..bd1a11d --- /dev/null +++ b/src/main/java/spring/mvc/handler/mapping/AnnotationHandlerMapping.java @@ -0,0 +1,62 @@ +package spring.mvc.handler.mapping; + +import jakarta.servlet.http.HttpServletRequest; +import org.reflections.ReflectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import spring.mvc.handler.excution.HandlerExecution; +import spring.mvc.annotation.RequestMapping; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class AnnotationHandlerMapping implements HandlerMapping { + + private static final Logger log = LoggerFactory.getLogger(AnnotationHandlerMapping.class); + private Object[] basePackage; + private Map handlerExecutions = new HashMap<>(); + + public AnnotationHandlerMapping(Object... basePackage) { + this.basePackage = basePackage; + } + + public void initialize() { + ControllerScanner controllerScanner = new ControllerScanner(basePackage); + Map, Object> controllers = controllerScanner.getControllers(); + Set methods = getRequestMappingMethods(controllers.keySet()); + + for (Method method : methods) { + RequestMapping rm = method.getAnnotation(RequestMapping.class); + log.debug("register handlerExecution : url is {}, method is {}", rm.value(), rm.method()); + handlerExecutions.put(createHandlerKey(rm), + new HandlerExecution(controllers.get(method.getDeclaringClass()), method)); + } + + log.info("Initialized AnnotationHandlerMapping!"); + } + + private HandlerKey createHandlerKey(RequestMapping rm) { + return new HandlerKey(rm.value(), rm.method()); + } + + @SuppressWarnings("unchecked") + private Set getRequestMappingMethods(Set> controlleers) { + Set requestMappingMethods = new HashSet<>(); + for (Class clazz : controlleers) { + requestMappingMethods + .addAll(ReflectionUtils.getAllMethods(clazz, ReflectionUtils.withAnnotation(RequestMapping.class))); + } + return requestMappingMethods; + } + + @Override + public HandlerExecution getHandler(HttpServletRequest request) { + String requestUri = request.getRequestURI(); + RequestMethod rm = RequestMethod.valueOf(request.getMethod().toUpperCase()); + log.debug("requestUri : {}, requestMethod : {}", requestUri, rm); + return handlerExecutions.get(new HandlerKey(requestUri, rm)); + } +} \ No newline at end of file diff --git a/src/main/java/spring/mvc/handler/mapping/HandlerKey.java b/src/main/java/spring/mvc/handler/mapping/HandlerKey.java new file mode 100644 index 0000000..9d420ba --- /dev/null +++ b/src/main/java/spring/mvc/handler/mapping/HandlerKey.java @@ -0,0 +1,31 @@ +package spring.mvc.handler.mapping; + +import java.util.Objects; + +public class HandlerKey { + private String url; + private RequestMethod method; + + public HandlerKey(String url, RequestMethod method) { + this.url = url; + this.method = method; + } + + @Override + public String toString() { + return "HandlerKey [url= {}" + url + ", requestMethod=" + method + "]"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HandlerKey that = (HandlerKey) o; + return Objects.equals(url, that.url) && method == that.method; + } + + @Override + public int hashCode() { + return Objects.hash(url, method); + } +} diff --git a/src/main/java/spring/mvc/handler/mapping/HandlerMapping.java b/src/main/java/spring/mvc/handler/mapping/HandlerMapping.java new file mode 100644 index 0000000..ee9c692 --- /dev/null +++ b/src/main/java/spring/mvc/handler/mapping/HandlerMapping.java @@ -0,0 +1,7 @@ +package spring.mvc.handler.mapping; + +import jakarta.servlet.http.HttpServletRequest; + +public interface HandlerMapping { + Object getHandler(HttpServletRequest request); +} diff --git a/src/main/java/spring/mvc/handler/mapping/RequestMethod.java b/src/main/java/spring/mvc/handler/mapping/RequestMethod.java new file mode 100644 index 0000000..0ff13fb --- /dev/null +++ b/src/main/java/spring/mvc/handler/mapping/RequestMethod.java @@ -0,0 +1,5 @@ +package spring.mvc.handler.mapping; + +public enum RequestMethod { + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE +}