在上一篇我们实现了依赖注入功能【从零写javaweb框架】(五)实现依赖注入功能
现在编写一个ControllerHelper
通过ClassHelper,可以获取所有定义了Controller注解的类,然后再通过反射获取该类中所有带有Action注解的方法,获取Action注解中的请求表达式,进而获取请求方法与请求路径,封装一个请求对象(Request)与处理对象(Handler),最后将Request与Handler建立一个映射关系,放入一个Action Map中,并提供一个可根据请求方法与请求路径获取处理对象的方法。
以下步骤均在框架项目中进行
那么,根据上面所说,我们首先需要封装一个Request类,和Handler类。
Request类
package org.smart4j.framework.bean; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; /** * desc : 请求信息的封装 * Created by Lon on 2018/1/28. */ public class Request { /** * 请求方法(如GET和POST) */ private String requestMethod; /** * 请求路径 */ private String requestPath; public Request(String requestMethod, String requestPath) { this.requestMethod = requestMethod; this.requestPath = requestPath; } public String getRequestMethod() { return requestMethod; } public String getRequestPath() { return requestPath; } /** * 这个方法之前没见过,查资料之后才知道: * reflectionHashCode是通过反射得到当前对象的各个属性, * 然后将它们作字符串拼接(append),最后再得到拼接后的字符串的哈希码 */ @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } /** * reflectionEquals与reflectionHashCode相对应 */ @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } }
Handler类
package org.smart4j.framework.bean; import java.lang.reflect.Method; /** * desc : 封装Action信息 * Created by Lon on 2018/1/28. */ public class Handler { /** * Controller类 */ private Class<?> controllerClass; /** * Action方法 */ private Method actionMethod; public Handler(Class<?> controllerClass, Method actionMethod) { this.controllerClass = controllerClass; this.actionMethod = actionMethod; } public Class<?> getControllerClass() { return controllerClass; } public Method getActionMethod() { return actionMethod; } }
最后就是我们要写的ControllerHelper:
package org.smart4j.framework.helper; import org.smart4j.framework.annotation.Action; import org.smart4j.framework.bean.Handler; import org.smart4j.framework.bean.Request; import org.smart4j.framework.util.ArrayUtil; import org.smart4j.framework.util.CollectionUtil; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * desc : 控制器助手类 * Created by Lon on 2018/1/28. */ public final class ControllerHelper { /** * 用于存放请求与处理器之间的映射关系(Action Map) */ private static final Map<Request, Handler> ACTION_MAP = new HashMap<Request, Handler>(); static { //获取所有Controller类 Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet(); if (CollectionUtil.isNotEmpty(controllerClassSet)){ //遍历controllerClassSet for (Class<?> controllerClass : controllerClassSet){ //获取Controller类中定义的方法 Method[] methods = controllerClass.getDeclaredMethods(); if (ArrayUtil.isNotEmpty(methods)){ //遍历这些Controller类中的方法 for (Method method : methods){ //判断当前方法是否带有Action注解 if (method.isAnnotationPresent(Action.class)){ //从Action注解中获取URL映射规划 Action action = method.getAnnotation(Action.class); String mapping = action.value(); //验证URL映射规划 if (mapping.matches("\\w+:/\\w*")){ String[] array = mapping.split(":"); if (ArrayUtil.isNotEmpty(array) && array.length == 2){ //获取请求方法与请求路径 String requestMethod = array[0]; String requestPath = array[1]; Request request = new Request(requestMethod, requestPath); Handler handler = new Handler(controllerClass, method); //初始化Action Map ACTION_MAP.put(request, handler); } } } } } } } } /** * 获取Handler */ public static Handler getHandler(String requestMethod, String requestPath){ Request request = new Request(requestMethod, requestPath); return ACTION_MAP.get(request); } }
最后来一张框架目录:
总结:
这一篇里,我封装了Request和Handler,并写了ControllerHelper来维护维护Request与Handler之间的映射关系。
下一篇开始实现框架的初始化。