学习smart-framework-mvn分发

基于servlet 思路:java

  1. 启动时获取使用Controller 和 Request注解的类,存入map,并处理{}参数。
  2. 对servlet访问进行分发,访问的路径到map中取对应的类和方法,而后执行。

基础类

枚举

public enum HttpMethod {
    GET,POST,PUT,DELETE
}

须要的bean部分

RequestBean正则表达式

private HttpMethod requestMethod; //访问方式
private String requestUrl; //访问路径

ActionBean安全

private Class<?> actionClass; //类
private Method actionMethod; //方法

注解

Controlleride

@Target(ElementType.TYPE) //类级别
@Retention(RetentionPolicy.RUNTIME) //在运行时有效
@Documented
public @interface Controller {
    String value() default "";
}

Request性能

@Target(ElementType.METHOD) //方法级别
@Retention(RetentionPolicy.RUNTIME) //在运行时有效
@Documented
public @interface Request {
    String value() default ""; //url
    HttpMethod method() default HttpMethod.GET;
}

存储controller的map

public class RequestHandler {
    private static final Map<RequestBean, ActionBean> ACTIONMAP = new HashMap<>();

    public static Map<RequestBean, ActionBean> getActionMap() {
        return ACTIONMAP;
    }

    static {
        //获取全部action
        List<Class<?>> actionList = ClassHelper.getClassListByAnnotation(Controller.class);
        for (Class<?> actionClass : actionList) {
            Method[] actionMethods = actionClass.getDeclaredMethods();
            if (actionMethods != null && actionMethods.length > 0) {
                for (Method actionMethod : actionMethods) {
                    //是否包含path注解
                    if (actionMethod.isAnnotationPresent(Request.class)) {
                        String url = actionMethod.getAnnotation(Request.class).value();
                        HttpMethod method = actionMethod.getAnnotation(Request.class).method();
                        // 将请求路径中的占位符 {\w+} 转换为正则表达式 (\\w+)
                        url = url.replaceAll("\\{\\w+\\}", "(\\\\w+)");
                        ACTIONMAP.put(new RequestBean(method, url), new ActionBean(actionClass, actionMethod));
                    }
                }
            }
        }
    }

}

serlvet 分发

@WebServlet("/*")
public class DispatcherServlet extends HttpServlet{
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse) res;
        //方法 路径
        String currentRequestMethod = request.getMethod();
        String currentRequestURL = request.getPathInfo();

        // 屏蔽特殊请求
        if (currentRequestURL.equals("/favicon.ico")) {
            return;
        }
        Map<RequestBean, ActionBean> actionMap = RequestHandler.getActionMap();
        for (Map.Entry<RequestBean, ActionBean> actionEntry : actionMap.entrySet()) {
            RequestBean requestBean = actionEntry.getKey();
            String requestURL = requestBean.getRequestUrl(); // 正则表达式
            HttpMethod requestMethod = requestBean.getRequestMethod();

            // 获取正则表达式匹配器(用于匹配请求 URL 并从中获取相应的请求参数)
            Matcher matcher = Pattern.compile(requestURL).matcher(currentRequestURL);
            // 判断请求方法与请求 URL 是否同时匹配
            if (requestMethod.name().equals(currentRequestMethod) && matcher.matches()) {
                ActionBean actionBean = actionEntry.getValue();
                Class<?> actionClass = actionBean.getActionClass();
                Method actionMethod = actionBean.getActionMethod();

                //取出参数列表
                List<Object> params = new ArrayList<>();
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    String param = matcher.group(i);
                    // 若为数字,则须要强制转换,并放入参数列表中
                    Class<?>[] parameterTypes = actionBean.getActionMethod().getParameterTypes();
                    Class<?> parameterType = parameterTypes[i - 1];
                    if (parameterType.equals(String.class)) {
                        params.add(param);
                    }else if (parameterType.equals(int.class)) {
                        params.add(Integer.parseInt(param));
                    }else if (parameterType.equals(long.class)) {
                        params.add(Long.parseLong(param));
                    }else if (parameterType.equals(double.class)) {
                        params.add(Double.parseDouble(param));
                    }
                }

                try {
                    // 建立 Action 实例
                    Object actionInstance = actionClass.newInstance();
                    // 调用 Action 方法(传入请求参数)
                    actionMethod.setAccessible(true); // 取消类型安全检测(可提升反射性能)
                    Object result = actionMethod.invoke(actionInstance, params.toArray());
                    response.getWriter().print(JSON.toJSONString(result));
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

                //匹配到就跳出
                break;
            }

        }
    }
}
相关文章
相关标签/搜索