基于Dubbo的http自动测试工具分享

发表于:2018-1-08 10:37

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:xingoo    来源:博客园

分享:
  3、方法的执行
  第三个难点,就是前端传过来的参数都是字符串,比如:
  com.xingoo.test.Provider1Impl 是对应的class
  test1 是对应的方法
  100 是对应的参数
  java.lang.Long 是参数对应的类型
  怎么能把请求通过正确的dubbo provider执行呢?——答案 就是Bean
  因为在Spring的项目中,dubbo的provider都是一个单例的bean。因此可以直接通过applicationContext获得对应的bean,只要保证bean的名字能规律的映射过来就行。
  可以参考下面的获取bean的方法:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
// 非@import显式注入,@Component是必须的,且该类必须与main同包或子包
// 若非同包或子包,则需手动import 注入,有没有@Component都一样
// 可复制到Test同包测试
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringUtils.applicationContext == null){
SpringUtils.applicationContext  = applicationContext;
}
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
  在真正的实现类上,需要指定bean的名字:
@Service("Provider1Impl")
public class Provider1Impl implements ProviderApi {
...
}
然后利用反射,就可以执行这个bean的特定方法了:
// 反射拿到对应的class
Class cla = Thread.currentThread().getContextClassLoader().loadClass(clazz);
// 在appContext中拿到对应的bean
Object bean = SpringUtils.getBean(cla.getSimpleName());
// 格式化参数与参数类型
Class<?>[] parameterTypes = DubboApiUtils.paramTypeFormat(types);
Object[] parameters = DubboApiUtils.paramsFormat(params,types);
// 通过反射调用对应的方法
return cla.getMethod(method, parameterTypes).invoke(bean,parameters);
  对应参数处理的两个方法是:
/**
* 根据字符串拼接,获得对应的参数类型数组
* @param types
* @return
*/
public static Class<?>[] paramTypeFormat(String types){
List<Class<?>> paramsClasses = new ArrayList<>();
for(String type : types.split(",")){
try {
paramsClasses.add(Class.forName(type));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return paramsClasses.toArray(new Class[]{});
}
/**
* 根据参数类型,转换类型
* @param paramStr
* @param types
* @return
*/
public static Object[] paramsFormat(String paramStr,String types){
Class<?>[] classes = paramTypeFormat(types);
List<Object> formats = new ArrayList<>();
String[] params = paramStr.split(",");
for(int i =0;i<classes.length; i++){
//todo 简单粗暴,有其他的需要再加吧
if("Long".equals(classes[i].getSimpleName())){
formats.add(Long.valueOf(params[i]));
}else{
formats.add(params[i]);
}
}
return formats.toArray();
}
  4、商品自动请求描述信息
  最后就是jquery基于ajax请求,查询对应的接口结果就行了。需要注意ajax的同步问题:
$.ajax({
type : "post",
url : "xxxxx",
data : {xxx:xxx},
async : false,
success : function(r){
//todo
}
});
  总结
  总结来说,下面是遇到的问题和简单的对应办法:
  1、如何扫描工程或者普通web项目 某个包下的class——通过classloader获得路径,直接遍历file即可
  2、如何扫描jar中某个包下的class——通过JarFile获得对应的JarEntry
  3、如何获取Spring Boot中的Bean——通过实现ApplicationContextAware接口,获取applicationContext的引用
  4、如何动态执行某个对象的特定方法——基于反射method.invoke,需要注意传入的参数与类型问题
  通过这样一个小工具,又对反射有了更进一步的了解。:-)))))))))

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
100家互联网大公司java笔试题汇总,填问卷领取~

精彩评论

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号