dubbox rest
问题描述
今天在使用dubbox的时候,在启动服务的时候报出一个错误,导致应用无法启动,错误的提示信息为:
Initializationofbeanfailed;nestedexceptionisjava.lang.RuntimeException:RESTEASY003130:Classisnotarootresource.It,oroneofitsinterfacesmustbeannotatedwith@Path
dubbox是在dubbo的基础上进行了restFul的扩展,使用了JAX-RS的扩展,因此可以支持restFul的调用,默认的调用方式应该为:
Interface:
@Path("interface/doSomething")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
publicinterfaceTestService{
@POST
@Path("run")
booleantest(TestDTOdto);
}
InterfaceImplements:
@Service
publicclassTestServiceImplimplementsTestService{
@Override
publicbooleantest(TestDTOdto){
//doSomething.......
}
}
由于dubbox是基于dubbo实现的,当我们有某些方法不想再提供restFul的接口时,只是提供dubbo的调用,该怎么做呢?
于是我想当然的这么做了:
publicinterfaceTestService{
booleantest(TestDTOdto);
}
我把interface中的JAX-RS的注解去除了,这样就只是提供dubbo的调用方式,而不提供restFul的调用了,然后当我启动项目的时候,就报了上面的错误……
问题原因
找了好多资料,找到了原因所在,因为dubbox支持JAX-RS,因此加入相应的Jar文件,其中就有resteasy,在其中的一个类ResourceMethodRegistry.java中的addResourceFactory()方法,找到了问题原因:
/**
*ResourceFactory.getScannableClass()defineswhatclassshouldbescanned
*forJAX-RSannotations.Theclassandanyimplementedinterfacesarescannedforannotations.
*
*@paramref
*@parambasebaseURIpathforanyresourcesprovidedbythefactory,inadditiontorootPath
*/
publicvoidaddResourceFactory(ResourceFactoryref,Stringbase)
{
Class<?>clazz=ref.getScannableClass();
Classrestful=GetRestful.getRootResourceClass(clazz);
if(restful==null)
{
Stringmsg=Messages.MESSAGES.classIsNotRootResource(clazz.getName());
for(Classintf:clazz.getInterfaces())
{
msg+=""+intf.getName();
}
thrownewRuntimeException(msg);
}
addResourceFactory(ref,base,restful);
}
可以看到ResourceFactory.getScannableClass()定义了扫描哪些class文件,进入看一下具体的实现:
publicclassDubboResourceFactoryimplementsResourceFactory{
privateObjectresourceInstance;
privateClassscannableClass;
publicDubboResourceFactory(ObjectresourceInstance,ClassscannableClass){
this.resourceInstance=resourceInstance;
this.scannableClass=scannableClass;
}
publicClass<?>getScannableClass(){
returnscannableClass;
}
}
这里只给出部分源码,从此可以看出scannableClass是由dubbo注解的class,因此可以明白其报错的原因,JAX-RS会扫描被dubbo注解的class实现的interface,由于interface没有注解@Path,因此抛出了异常。
总结
使用dubbox后,提供dubbo服务的类必须注解@Path,即使该类中没有提供restFul的调用,否则会报出”Classisnotarootresource”的异常,那我们有的类中的确没有方法需要提供restFul调用的时候该怎么办呢?可以在方法上不加任何注解,这样做的话只可以进行dubbo方式的调用
@Path("interface/doSomething")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
publicinterfaceTestService{
booleantest(TestDTOdto);
}
ps:本文为转载自wtopps的专栏,没有它义,收藏好文!