从阿里重新维护Dubbo开始,这个开源项目突然变得特别活跃。
新推出的2.6.0版本更合并了当当网Dubbox的部分特性,现已支持开发Rest接口。下面是笔者的尝试,请参考。
提供者
1、定义接口
ServiceFacade.java
public interface ServiceFacade {
String hello();
}
2、实现接口
ServiceImpl.java
@Path("demo")
public class ServiceImpl implements ServiceFacade {
@Override
@Path("hello")
@GET
public String hello() {
return "Hello World! ";
}
}
REST风格基于标准的Java REST API——JAX-RS 2.0实现,访问URL为:
http://ip:port/demo/hello
这里的@Path
、@GET
来自jaxrs-api.jar,dubbo-2.6.0没有自带,需要自己依赖:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.12.Final</version>
</dependency>
3、暴露接口
provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!-- use multicast registry center to export service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="2080"/>
<dubbo:protocol name="rest" port="8080" server="tomcat"/>
<bean id="demoService" class="com.free.dubbo.demo.provider.ServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.free.dubbo.demo.provider.ServiceFacade" ref="demoService" protocol="dubbo,rest"/>
</beans>
上面server笔者使用了tomcat,这里是可选的(netty、jetty、servlet等),因此也需要添加下面的依赖:
<!--for rest protocal-->
<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>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
4、启动提供者
Provider.java
public class Provider {
public static void main(String[] args) throws Exception{
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("classpath:provider.xml");
context.start();
// 阻塞
System.in.read();
}
}
消费者
1、定义dubbo接口引用
consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:application name="demo-consumer"/>
<!-- use multicast registry center to discover service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
local regular interface -->
<dubbo:reference id="demoService" check="true" interface="com.free.dubbo.demo.provider.ServiceFacade"/>
</beans>
这里只是定义了dubbo协议引用,rest接口像普通url访问就可以了。
2、调用接口
ConsumerDemo.java
public class ConsumerDemo {
public static void main(String[] args) throws Exception{
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("classpath:consumer.xml");
context.start();
// Test dubbo protocal
ServiceFacade serviceDemo = context.getBean(ServiceFacade.class);
System.out.println("Dubbo result: " + serviceDemo.hello());
// Test rest protocal
HttpClient client = HttpClientBuilder.create()
.build();
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(3000)
.setSocketTimeout(3000)
.build();
HttpGet httpGet = new HttpGet("http://localhost:8080/demo/hello");
httpGet.setConfig(config);
HttpResponse httpResponse = client.execute(httpGet);
int statusCode = httpResponse.getStatusLine()
.getStatusCode();
if (200 != statusCode) {
System.out.println("WARN: Response code is" + statusCode);
}
String response = EntityUtils.toString(httpResponse.getEntity(), Charset.forName("UTF-8"));
Assert.notNull(response, "Return null when invoke rest interface. ");
System.out.println("Rest result: " + response);
}
}
输出:
Dubbo result: Hello World!
Rest result: Hello World!
Process finished with exit code 0
如果想了解更多,可以参考
1、在Dubbo中开发REST风格的远程调用:
https://dangdangdotcom.github.io/dubbox/rest.html
2、Dubbo主页:http://dubbo.io