在上一篇我们实现了依赖注入功能【从零写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之间的映射关系。
下一篇开始实现框架的初始化。