java反射机制实际应用

网上搜到的大部分是简单的demo,实际解析则跟业务逻辑有关系.
需要注意的是jdk1.7只能对类取参数名,jdk1.8之后才提供了对接口获取参数名的实现,且还需勾选下面的配置,保存接口的参数信息。
1

public class ControllerHttpBean {
    /**
     * 请求方式,GET、POST
     */
    private String reqMethod;
    /**
     * 接口路径
     */
    private String iface;
    /**
     * 方法名
     */
    private String methodName;
    /**
     * 方法名
     */
    private List<ParameterBean> params;
    
    public String getReqMethod() {
        return reqMethod;
    }
    public void setReqMethod(String reqMethod) {
        this.reqMethod = reqMethod;
    }
    public String getIface() {
        return iface;
    }
    public void setIface(String iface) {
        this.iface = iface;
    }
    public String getMethodName() {
        return methodName;
    }
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
	public List<ParameterBean> getParams() {
		return params;
	}
	public void setParams(List<ParameterBean> params) {
		this.params = params;
	}
}
public class ParameterBean {

	/**
	 * 完整类名
	 */
	private String className;
	/**
	 * 方法参数名
	 */
	private String parameterName;
	/**
	 * 子对象数据
	 */
	private List<ParameterBean> subParams = new ArrayList<ParameterBean>();
	
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	public String getParameterName() {
		return parameterName;
	}
	public void setParameterName(String parameterName) {
		this.parameterName = parameterName;
	}
	public List<ParameterBean> getSubParams() {
		return subParams;
	}
	public void setSubParams(List<ParameterBean> subParams) {
		this.subParams = subParams;
	}
}

public class Parse {
	private static LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();

	@SuppressWarnings("rawtypes")
	public List<ControllerHttpBean> parseClass(String className) {
		List<ControllerHttpBean> controllerHttpBeans = null;
		try {
			Class clazz = Class.forName(className);
			controllerHttpBeans = parseMethod(clazz.getDeclaredMethods());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return controllerHttpBeans;
	}

	/**
	 * 解析方法
	 * 
	 * @param methods
	 */
	private List<ControllerHttpBean> parseMethod(Method[] methods) {
		List<ControllerHttpBean> controllerHttpBeans = new ArrayList<ControllerHttpBean>();
		if (methods != null && methods.length > 0) {
			ControllerHttpBean controllerHttpBean = null;
			for (Method method : methods) {
				if (method.getModifiers() != 1) {
					// 只根据public的方法来生成
					continue;
				}
				// rest消息公共回复类
				controllerHttpBean = new ControllerHttpBean();
				controllerHttpBean.setMethodName(method.getName());
				// 注解
				parseAnnotation(method, controllerHttpBean);
				// 参数
				controllerHttpBean.setParams(parseParams(method));
				controllerHttpBeans.add(controllerHttpBean);
			}
		}
		return controllerHttpBeans;
	}

	/**
	 * 获取方法参数类型和参数名
	 * 
	 * @param method
	 * @return
	 */
	private List<ParameterBean> parseParams(Method method) {
		List<ParameterBean> params = new ArrayList<ParameterBean>();
		String[] paramNames = u.getParameterNames(method);
		for (int i = 0; i < method.getParameterTypes().length; i++) {
			ParameterBean bean = new ParameterBean();
			String className = method.getParameterTypes()[i].getName();
			if (className.equals("javax.servlet.http.HttpServletRequest")
					|| className
							.equals("javax.servlet.http.HttpServletResponse")) {
				// controller层这两个参数不做解析
			} else {
				bean.setClassName(className);
				if (!CheckEmptyUtil.isEmpty(paramNames)) {
					bean.setParameterName(paramNames[i]);
				}
				if (className.indexOf("com") >= 0){
					// com打头的,视为自定义的数据类型
					bean.setSubParams(parseParams(className));
				}
				params.add(bean);
			}
			;
		}
		return params;
	}

	/**
	 * 解析参数中的属性
	 * 
	 * @param parameterBean
	 * @return
	 */
	private List<ParameterBean> parseParams(String className ) {
		List<ParameterBean> parameterBeans = new ArrayList<ParameterBean>();
		try {
			@SuppressWarnings("rawtypes")
			Class clazz = Class.forName(className);
			Field[] fields = clazz.getDeclaredFields();
			if (fields!=null && fields.length>0){
				ParameterBean parameterBean = null;
				for (Field field:fields){
					if (field.getName().equals("serialVersionUID")){
						// 序列化属性不解析
						continue;
					}
					parameterBean = new ParameterBean();
					parameterBean.setClassName(field.getType().getName());
					parameterBean.setParameterName(field.getName());
					if (parameterBean.getClassName().indexOf("com")>=0){
						// 如果对象还有自定义的对象,则继续解析
						parameterBean.setSubParams(parseParams(parameterBean.getClassName()));
					}
					parameterBeans.add(parameterBean);
				}
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return parameterBeans;
	}

	/**
	 * 通过方法注解获取method和path
	 * 
	 * @param method
	 * @param controllerHttpBean
	 */
	private void parseAnnotation(Method method,
			ControllerHttpBean controllerHttpBean) {
		Annotation[] annotations = method.getAnnotations();
		if (annotations != null && annotations.length > 0) {
			for (Annotation annotation : annotations) {
				String str = annotation.toString();
				if (str.indexOf("@org.springframework.web.bind.annotation.RequestMapping") >= 0) {
					RequestMapping requestMapping = (RequestMapping) annotation;
					controllerHttpBean
							.setReqMethod(getReqMethod(requestMapping));
					controllerHttpBean.setIface(getValue(requestMapping));
					break;
				}
			}
		}
	}

	/**
	 * 获取路径值,没有时为null
	 * 
	 * @param annotation
	 * @return
	 */
	private String getValue(RequestMapping annotation) {
		if (annotation.value().length < 1) {
			return null;
		} else {
			return annotation.value()[0].toString();
		}
	}

	/**
	 * 获取Method,暂时只支持GET和POST
	 * 
	 * @param annotation
	 * @return
	 */
	private String getReqMethod(RequestMapping annotation) {
		if (annotation.method().length < 1) {
			return RequestMethod.GET.name();
		}
		for (RequestMethod requestMethod : annotation.method()) {
			if (requestMethod.equals(RequestMethod.GET)) {
				return RequestMethod.GET.name();
			} else if (requestMethod.equals(RequestMethod.POST)) {
				return RequestMethod.POST.name();
			}
		}
		return annotation.method()[0].name();
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值