dubbox rest

问题描述
今天在使用dubbox的时候,在启动服务的时候报出一个错误,导致应用无法启动,错误的提示信息为:
Initialization of bean failed; nested exception is java.lang.RuntimeException: RESTEASY003130: Class is not a root resource. It, or one of its interfaces must be annotated with @Path

dubbox是在dubbo的基础上进行了restFul的扩展,使用了JAX-RS的扩展,因此可以支持restFul的调用,默认的调用方式应该为:

Interface:

@Path("interface/doSomething")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface TestService {

    @POST
    @Path("run")
    boolean test(TestDTO dto);
}

Interface Implements:

@Service
public class TestServiceImpl implements TestService {

    @Override
    public boolean test(TestDTO dto) {
        //doSomething.......
    }
}

由于dubbox是基于dubbo实现的,当我们有某些方法不想再提供restFul的接口时,只是提供dubbo的调用,该怎么做呢?

于是我想当然的这么做了:


public interface TestService {

    boolean test(TestDTO dto);
}

我把interface中的JAX-RS的注解去除了,这样就只是提供dubbo的调用方式,而不提供restFul的调用了,然后当我启动项目的时候,就报了上面的错误……

问题原因
找了好多资料,找到了原因所在,因为dubbox支持JAX-RS,因此加入相应的Jar文件,其中就有resteasy,在其中的一个类ResourceMethodRegistry.java 中的addResourceFactory()方法,找到了问题原因:

/**
    * ResourceFactory.getScannableClass() defines what class should be scanned
    * for JAX-RS annotations.    The class and any implemented interfaces are scanned for annotations.
    *
    * @param ref
    * @param base base URI path for any resources provided by the factory, in addition to rootPath
    */
   public void addResourceFactory(ResourceFactory ref, String base)
   {
      Class<?> clazz = ref.getScannableClass();
      Class restful = GetRestful.getRootResourceClass(clazz);
      if (restful == null)
      {
         String msg = Messages.MESSAGES.classIsNotRootResource(clazz.getName());
         for (Class intf : clazz.getInterfaces())
         {
            msg += " " + intf.getName();
         }
         throw new RuntimeException(msg);
      }
      addResourceFactory(ref, base, restful);
   }

可以看到ResourceFactory.getScannableClass()定义了扫描哪些class文件,进入看一下具体的实现:

public class DubboResourceFactory implements ResourceFactory {

    private Object resourceInstance;
    private Class scannableClass;

    public DubboResourceFactory(Object resourceInstance, Class scannableClass) {
        this.resourceInstance = resourceInstance;
        this.scannableClass = scannableClass;
    }

    public Class<?> getScannableClass() {
        return scannableClass;
    }
}   

这里只给出部分源码,从此可以看出scannableClass是由dubbo注解的class,因此可以明白其报错的原因,JAX-RS会扫描被dubbo注解的class实现的interface,由于interface没有注解@Path,因此抛出了异常。

总结
使用dubbox后,提供dubbo服务的类必须注解@Path,即使该类中没有提供restFul的调用,否则会报出”Class is not a root resource”的异常,那我们有的类中的确没有方法需要提供restFul调用的时候该怎么办呢?可以在方法上不加任何注解,这样做的话只可以进行dubbo方式的调用

@Path("interface/doSomething")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface TestService {

    boolean test(TestDTO dto);
}


ps:本文为转载 自 wtopps的专栏,没有它义,收藏好文!

猜你喜欢

转载自beijing2008gejun.iteye.com/blog/2422833