基於servlet 思路:java
public enum HttpMethod { GET,POST,PUT,DELETE }
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; }
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)); } } } } } }
@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; } } } }