原文: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開銷。
...