原文:http://dangdangdotcom.github.io/dubbox/rest.htmlphp
dubbo支持多种远程调用方式,例如dubbo RPC(二进制序列化 + tcp协议)、http invoker(二进制序列化 + http协议,至少在开源版本没发现对文本序列化的支持)、hessian(二进制序列化 + http协议)、WebServices (文本序列化 + http协议)等等,但缺少对当今特别流行的REST风格远程调用(文本序列化 + http协议)的支持。html
有鉴于此,咱们基于标准的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的简写),为dubbo提供了接近透明的REST调用支持。因为彻底兼容Java标准API,因此为dubbo开发的全部REST服务,将来脱离dubbo或者任何特定的REST底层实现通常也能够正常运行。java
特别值得指出的是,咱们并不须要彻底严格遵照REST的原始定义和架构风格。即便著名的Twitter REST API也会根据状况作适度调整,而不是机械的遵照原始的REST风格。git
附注:咱们将这个功能称之为REST风格的远程调用,即RESTful Remoting(抽象的远程处理或者调用),而不是叫RESTful RPC(具体的远程“过程”调用),是由于REST和RPC自己能够被认为是两种不一样的风格。在dubbo的REST实现中,能够说有两个面向,其一是提供或消费正常的REST服务,其二是将REST做为dubbo RPC体系中一种协议实现,而RESTful Remoting同时涵盖了这个面向。github
标准的Restful框架:JAX-RS(JAVATM API FOR RESTFUL WEB SEVICES),具体实现有:web
①.Apache CXF——XFire和Celtix的合并(一个由IONA赞助的开源ESB,最初寄存在ObjectWeb上),开源的Web服务框架。spring
②.Jersey——Sun公司提供的JAX-RS的参考实现。json
③.RESTEasy——Jboss公司的实现。tomcat
④.Restlet——JAX-RS以前就存在的最先的REST框架。服务器
⑤.Apache Wink,一个Apache软件基金会孵化器中的项目,其服务模块实现JAX-RS规范
经常使用注解:
@PATH,接口请求的路径
@GET、@PUT、@DELETE、@POST,分别对应着查、改、删、增四种Http请求类型
@Produces,标记返回的MIME媒体类型。理解:能够接受的出参类型,通常为json、xml
@Consumes,标记可接受的MIME媒体类型。理解:能够接受的入参类型。
@PathParam、@QueryParam、@FormParam、@HeaderParam、@CookieParam、@MatrixParam,请求参数的类型
通常放在实现类中,防止接口污染,保证接口的可维护性、可扩展性。
接口和实现类同时配置注解,则实现类生效,接口的注解会被直接忽略。
<dubbo:protocol name="rest" server="jetty"/>
非单独启动进程,可使用外部容器:
<dubbo:protocol name="rest" server="servlet"/>
web.xml:
<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/META-INF/spring/dubbo-demo-provider.xml</param-value> </context-param> <listener> <listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
即必须将dubbo的BootstrapListener和DispatherServlet添加到web.xml,以完成dubbo的REST功能与外部servlet容器的集成。
注意:若是你是用spring的ContextLoaderListener来加载spring,则必须保证BootstrapListener配置在ContextLoaderListener以前,不然dubbo初始化会出错。
其实,这种场景下你依然能够坚持用嵌入式server,但外部应用服务器的servlet容器每每比嵌入式server更增强大(特别是若是你是部署到更健壮更可伸缩的WebLogic,WebSphere等),另外有时也便于在应用服务器作统一管理、监控等等。
第一种方式,用JAX-RS标准的@Context annotation:
public User getUser(@PathParam("id") Long id, @Context HttpServletRequest request) {
System.out.println("Client address is " + request.getRemoteAddr());
}
第二种方式,用dubbo中经常使用的RpcContext:(代码具备入侵式,将来可能重构,server=jetty、tomcat、servlet、tjws才能用)
public User getUser(@PathParam("id") Long id) {
System.out.println("Client address is " + RpcContext.getContext().getRemoteAddressString());
}
<dubbo:protocol name="rest" port="8888"/>
web上下午contextPath配置:
<dubbo:protocol name="rest" port="8888" contextpath="services" server="servlet"/>
Dubbo的REST支持用GZIP压缩请求和响应的数据,以减小网络传输时间和带宽占用,但这种方式会也增长CPU开销。
...