<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>/services/*</url-pattern> </servlet-mapping>
在service-provider.xml配置如下
<!-- use the external tomcat or other server with the servlet approach; the port and contextpath must be exactly the same as those in external server --> <dubbo:protocol name="rest" port="8888" contextpath="services" server="servlet"/>
这样的配置是在应用发布在webapps的ROOT根路径下的配置,访问地址如下:
http://localhost:8888/services/...
当应用发布在非ROOT中是,比如webapps/provider/路径下,此时rest服务总是访问不到,而在dubbox的说明中有如下文字:
注意:如果你是选用外部应用服务器做rest server,即配置: <dubbo:protocol name="rest" port="8888" contextpath="services" server="servlet"/> 则必须保证这里设置的port、contextpath,与外部应用服务器的端口、DispatcherServlet的上下文路径(即webapp path加上servlet url pattern)保持一致。例如,对于部署为tomcat ROOT路径的应用,这里的contextpath必须与web.xml中DispacherServlet的<url-pattern/>完全一致: <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
但是修改了service-provider.xml中contextpath为/provider/services也不行
报错信息如下:
com.alibaba.dubbo.rpc.RpcException: Since you are using server='servlet', make sure that the 'contextpath' property starts with the path of external webapp at com.alibaba.dubbo.rpc.protocol.rest.RestProtocol.doExport(RestProtocol.java:104)
查看RestProtocol源码
String webappPath = servletContext.getContextPath(); if (StringUtils.isNotEmpty(webappPath)) { webappPath = webappPath.substring(1); if (!contextPath.startsWith(webappPath)) { throw new RpcException("Since you are using server='servlet', " + "make sure that the 'contextpath' property starts with the path of external webapp"); } contextPath = contextPath.substring(webappPath.length()); if (contextPath.startsWith("/")) { contextPath = contextPath.substring(1); } }
代码逻辑一目了然,if (!contextPath.startsWith(webappPath)) {
需要将service-provider.xml中contextpath修改为provider/services即可,不带/前缀