All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xiaoleilu.hulu.ActionMethod Maven / Gradle / Ivy

package com.xiaoleilu.hulu;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import com.xiaoleilu.hulu.annotation.Route;
import com.xiaoleilu.hulu.exception.ActionException;
import com.xiaoleilu.hulu.interceptor.Interceptor;
import com.xiaoleilu.hutool.Log;
import com.xiaoleilu.hutool.StrUtil;

/**
 * Action方法
* 单例存在于容器中 * * @author xiaoleilu */ public class ActionMethod { /** 过滤器执行位置记录器 */ private static ThreadLocal interceptorPosition = new ThreadLocal(); private Object action; //Action对象 private Method method; //Action方法 private String requestPath; //请求路径 private String httpMethod; //HTTP方法(GET、POST等) private Interceptor[] interceptors; //过滤器 // -------------------------------------------------------------------- Constructor start public ActionMethod(Object action, Method method) { this.action = action; this.method = method; this.method.setAccessible(true); // 取消安全检查,加快invoke速度 // 生成请求路径 this.requestPath = genRequestPath(); } public ActionMethod(Object action, Method method, Interceptor[] interceptors) { this(action, method); this.interceptors = interceptors; } // -------------------------------------------------------------------- Constructor end // ------------------------------------------------------------- Setters and Getters start /** * 获得请求路径 * * @return 请求路径 */ public String getRequestPath() { return requestPath; } /** * 获得Action方法 * * @return Action方法 */ protected Method getMethod() { return this.method; } // ------------------------------------------------------------- Setters and Getters end /** * 执行Action方法
* 同时会执行过滤器方法
* 此方法为递归调用,每次递归调用此方法,都会判断执行到了第几个拦截器,从而执行拦截器。
* 当拦截器数量执行完毕后,执行本体方法 * * @throws ActionException */ public void invoke() throws ActionException { Integer position = interceptorPosition.get(); if (position == null) { position = 0; } if (interceptors != null && position < interceptors.length) { //执行过滤器,递归调用本方法 interceptorPosition.set(position + 1); interceptors[position].invoke(this); }else { //过滤器执行完毕,执行本体方法 try { this.method.invoke(this.action); } catch(InvocationTargetException te) { throw new ActionException(te.getCause()); } catch (Exception e) { throw new ActionException("Invoke action method error!", e); } // 执行了Action本体方法,说明过滤器使用完毕,清理游标防止重复执行 resetInterceptorPosition(); } } /** * 重置过滤器执行顺序游标
* 游标记录了执行到了第几个过滤器 */ protected void resetInterceptorPosition() { interceptorPosition.remove(); } /** * 指定用户请求的HTTP方法是否和定义的方法匹配
* 用户只有在Route注解中定义方法后才会匹配有效性 * @return 是否匹配 */ protected boolean isHttpMethodMatch() { if(StrUtil.isNotBlank(httpMethod) && httpMethod.equalsIgnoreCase(Request.getServletRequest().getMethod()) == false) { if(HuluSetting.isDevMode) { Log.warn("Request [{}] method [{}] is not match [{}]", requestPath, Request.getServletRequest().getMethod(), httpMethod); } return false; } return true; } // ------------------------------------------------------------- Private method start /** * 生成请求路径
* @return 请求路径 */ private String genRequestPath() { // 根据Annotation自定义请求路径 String routePath = getRouteAnnotationPath(this.method); //提取HTTP方法名(如果路径是类似于get:/test/testMethod) if(routePath != null && routePath.contains(":")) { final List methodAndPath = StrUtil.split(routePath, ':', 2); this.httpMethod = methodAndPath.get(0).trim().toUpperCase(); routePath = methodAndPath.get(1).trim(); } return fixRoutePath(routePath); } /** * 修正请求路径
* 1、去除空白符 * 2、去除尾部斜杠 * 3、补全开头的斜杠 * @param routePath 原请求路径 * @return 修正后的请求路径 */ private String fixRoutePath(String routePath) { if(StrUtil.isBlank(routePath)) { //用户没有定义Annotation,使用标准请求路径 return genNormalRequestPath(); } routePath = StrUtil.cleanBlank(routePath); //去除空白符 routePath = StrUtil.removeSuffix(routePath, StrUtil.SLASH); // 去除尾部斜杠 if (routePath.startsWith(StrUtil.SLASH) == false) { routePath = StrUtil.SLASH + routePath; //在路径前补全“/” } return routePath; } /** * 生成标准的请求路径 * @return 标准请求路径 */ private String genNormalRequestPath() { final String actionName = StrUtil.removeSuffix(this.action.getClass().getSimpleName(), HuluSetting.actionSuffix).toLowerCase(); return String.format("/%s/%s", actionName, this.method.getName()); } /** * 获得Route注解的自定义请求路径
* @param method Action方法 * @return 处理后的请求路径,无定义为null */ private String getRouteAnnotationPath(Method method) { final Route routeAnnotation = method.getAnnotation(Route.class); if (null == routeAnnotation) { return null; } String routePath = routeAnnotation.value(); if (StrUtil.isBlank(routePath)) { //index请求 return StrUtil.EMPTY; } return routePath; } // ------------------------------------------------------------- Private method end }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy