使用dubbox为dubbo提供REST服务

Dubbo 是阿里多年前开源的一套服务治理框架,在众多互联网企业里应用广泛。当当在dubbo的基础上开发了 dubbox (Dubbo eXtensions),支持REST风格远程调用。本文在 服务治理框架dubbo上手指南 的基础上使用dubbox提供的REST服务。 

准备环境

首先参考 服务治理框架dubbo上手指南 ,实现自己的dubbo服务。在此基础上,让我们来看看 在Dubbo中开发REST风格的远程调用 。REST的优势就不多说了,本文关注的是快速搭建环境。

光看dubbox的官方文档稍微有一点儿坑,因为它对于maven依赖的描述基本没有。Dubbo本身的维护已经不太活跃了,最新的版本是 2.5.4-SNAPSHOT 。当当接下了维护的重任,目前的最新版是 dubbox-2.8.4 ,其实groupId和artifactId还是原来的不变,只是版本号有变化罢了。所以首先让我们来升级一下依赖,在 helloImpl 的 pom.xml 里升级dubbo:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.8.4</version>
    <exclusions>
        <exclusion>
            <artifactId>spring-expression</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-beans</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-aop</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
    </exclusions>
</dependency>

使用 mvn dependency:tree 命令可以看到,dubbox依赖于spring的 3.2.9.RELEASE 版本。由于我们上一个dubbo的练习中使用了spring的 4.2.4.RELEASE 版本,所以会有依赖冲突。解决冲突的办法有两个,一是把我们的spring降级到dubbox依赖的3.2.9.RELEASE 版本,二是使用exclusions把dubbox依赖的几个spring包都解除掉。这里我们的配置采用了后者。除了dubbox本身,我们还需要以下的依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.7</version>
</dependency>

再然后就是 dubbox自身的依赖 ,不管有用没用,先加进来再说:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>3.0.7.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-client</artifactId>
    <version>3.0.7.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
</dependency>

<!-- 如果要使用json序列化 -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson-provider</artifactId>
    <version>3.0.7.Final</version>
</dependency>

<!-- 如果要使用xml序列化 -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <version>3.0.7.Final</version>
</dependency>

<!-- 如果要使用netty server -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-netty</artifactId>
    <version>3.0.7.Final</version>
</dependency>

<!-- 如果要使用Sun HTTP server -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jdk-http</artifactId>
    <version>3.0.7.Final</version>
</dependency>

<!-- 如果要使用tomcat server -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>8.0.11</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-logging-juli</artifactId>
    <version>8.0.11</version>
</dependency>

这样就把所有的依赖都解决了,现在可以修改dubbo的服务配置文件provider.xml 了:

<!--<dubbo:protocol name="dubbo" port="19880" />-->
<dubbo:protocolname="rest"server="tomcat"port="9090" />

把原来的dubbo协议注释掉,增加rest协议,用内置的tomcat启动,端口为9090。这里为了清晰起见,注释掉了dubbo协议,而实际上协议是可以并存的。接下来可以改造我们的 HelloServiceImpl 了。直接放上最后的代码:

package org.ggg.hello.service.provider;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.ggg.hello.service.HelloService;

@Path("demo")
public class HelloServiceImpl implements HelloService {

    @GET
    @Path("greeting")
    @Produces("application/json; charset=UTF-8")
    public String sayHello(@QueryParam("name") String name) {
        return "Hello " + name;
    }
}

首先我们在类上增加了一个注解 @Path("demo") ,它指定访问HelloService的URL相对路径是/demo,即 http://localhost:9090/demo 。方法上也有一个 @Path("greeting") ,相当于访问这个方法的URL为 http://localhost:9090/demo/greeting 。 @GET 就不用多说了, @Produces 可以在Response Headers里增加 Content-Type: application/json;charset=UTF-8 。如果有必要,也可以来一个相对应的 @Consumes("application/json") 。在参数上还有一个注解 @QueryParam("name") ,有了它就可以通过URL参数的方式传值过来了。启动 Provider 之后,没有意外的话应该能看见控制台的日志: Starting ProtocolHandler [“http-nio-9090”] ,接下来就可以通过访问 http://localhost:9090/demo/greeting?name=ggg 来访问我们的服务了。屏幕上可以看到: Hello ggg 。

至此,我们以一个并不太RESTful的URL完成了一个REST请求。

猜你喜欢

转载自jaesonchen.iteye.com/blog/2338292