diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
index 6a96eb0d..b393fddb 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
@@ -20,6 +20,7 @@
spring-cloud-dubbo-provider-sample
spring-cloud-dubbo-consumer-sample
spring-cloud-dubbo-provider-web-sample
+ spring-cloud-dubbo-servlet-gateway-sample
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml
new file mode 100644
index 00000000..75b6d18e
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+ spring-cloud-alibaba-dubbo-examples
+ org.springframework.cloud
+ 0.2.2.BUILD-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ org.springframework.cloud
+ spring-cloud-dubbo-servlet-gateway-sample
+ Spring Cloud Dubbo Servlet Gateway Sample
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dubbo-sample-api
+ ${project.version}
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java
new file mode 100644
index 00000000..0ad4d68e
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.alibaba.dubbo.bootstrap;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+/**
+ * Dubbo Spring Cloud Servlet Gateway Bootstrap
+ */
+@EnableDiscoveryClient
+@EnableAutoConfiguration
+@EnableFeignClients
+@ServletComponentScan(basePackages = "org.springframework.cloud.alibaba.dubbo.gateway")
+public class DubboSpringCloudServletGatewayBootstrap {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(DubboSpringCloudServletGatewayBootstrap.class)
+ .properties("spring.profiles.active=nacos")
+ .run(args);
+ }
+}
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java
new file mode 100644
index 00000000..46fcf5e2
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java
@@ -0,0 +1,188 @@
+package org.springframework.cloud.alibaba.dubbo.gateway;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.dubbo.rpc.service.GenericException;
+import org.apache.dubbo.rpc.service.GenericService;
+import org.springframework.cloud.alibaba.dubbo.http.MutableHttpServerRequest;
+import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
+import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
+import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
+import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
+import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
+import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContext;
+import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
+import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.PathMatcher;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.util.UriComponents;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
+
+@WebServlet(urlPatterns = "/dsc/*")
+public class DubboGatewayServlet extends HttpServlet {
+
+ private final DubboServiceMetadataRepository repository;
+
+ private final DubboTransportedMetadata dubboTransportedMetadata;
+
+ private final DubboGenericServiceFactory serviceFactory;
+
+ private final DubboGenericServiceExecutionContextFactory contextFactory;
+
+ private final PathMatcher pathMatcher = new AntPathMatcher();
+
+ public DubboGatewayServlet(DubboServiceMetadataRepository repository,
+ DubboGenericServiceFactory serviceFactory,
+ DubboGenericServiceExecutionContextFactory contextFactory) {
+ this.repository = repository;
+ this.dubboTransportedMetadata = new DubboTransportedMetadata();
+ dubboTransportedMetadata.setProtocol("dubbo");
+ dubboTransportedMetadata.setCluster("failover");
+ this.serviceFactory = serviceFactory;
+ this.contextFactory = contextFactory;
+ }
+
+ public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+
+ // /g/{app-name}/{rest-path}
+ String requestURI = request.getRequestURI();
+ // /g/
+ String servletPath = request.getServletPath();
+
+ String part = StringUtils.substringAfter(requestURI, servletPath);
+
+ String serviceName = StringUtils.substringBetween(part, "/", "/");
+
+ // App name= spring-cloud-alibaba-dubbo-web-provider (127.0.0.1:8080)
+
+ String restPath = StringUtils.substringAfter(part, serviceName);
+
+ // 初始化 serviceName 的 REST 请求元数据
+ repository.initialize(serviceName);
+ // 将 HttpServletRequest 转化为 RequestMetadata
+ RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
+
+ DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, clientMetadata);
+
+ if (dubboServiceMetadata == null) {
+ // if DubboServiceMetadata is not found, executes next
+ throw new ServletException("DubboServiceMetadata can't be found!");
+ }
+
+ RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
+
+ GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
+
+ // TODO: Get the Request Body from HttpServletRequest
+ byte[] body = getRequestBody(request);
+
+ MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(new HttpRequestAdapter(request), body);
+
+// customizeRequest(httpServerRequest, dubboRestMethodMetadata, clientMetadata);
+
+ DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, httpServerRequest);
+
+ Object result = null;
+ GenericException exception = null;
+
+ try {
+ result = genericService.$invoke(context.getMethodName(), context.getParameterTypes(), context.getParameters());
+ } catch (GenericException e) {
+ exception = e;
+ }
+ response.getWriter().println(result);
+ }
+
+ private byte[] getRequestBody(HttpServletRequest request) throws IOException {
+ ServletInputStream inputStream = request.getInputStream();
+ return StreamUtils.copyToByteArray(inputStream);
+ }
+
+ private static class HttpRequestAdapter implements HttpRequest {
+
+ private final HttpServletRequest request;
+
+ private HttpRequestAdapter(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getMethodValue() {
+ return request.getMethod();
+ }
+
+ @Override
+ public URI getURI() {
+ try {
+ return new URI(request.getRequestURL().toString() + "?" + request.getQueryString());
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ throw new RuntimeException();
+ }
+
+ @Override
+ public HttpHeaders getHeaders() {
+ return new HttpHeaders();
+ }
+ }
+
+// protected void customizeRequest(MutableHttpServerRequest httpServerRequest,
+// RestMethodMetadata dubboRestMethodMetadata, RequestMetadata clientMetadata) {
+//
+// RequestMetadata dubboRequestMetadata = dubboRestMethodMetadata.getRequest();
+// String pathPattern = dubboRequestMetadata.getPath();
+//
+// Map pathVariables = pathMatcher.extractUriTemplateVariables(pathPattern, httpServerRequest.getPath());
+//
+// if (!CollectionUtils.isEmpty(pathVariables)) {
+// // Put path variables Map into query parameters Map
+// httpServerRequest.params(pathVariables);
+// }
+//
+// }
+
+ private RequestMetadata buildRequestMetadata(HttpServletRequest request, String restPath) {
+ UriComponents uriComponents = fromUriString(request.getRequestURI()).build(true);
+ RequestMetadata requestMetadata = new RequestMetadata();
+ requestMetadata.setPath(restPath);
+ requestMetadata.setMethod(request.getMethod());
+ requestMetadata.setParams(getParams(request));
+ requestMetadata.setHeaders(getHeaders(request));
+ return requestMetadata;
+ }
+
+ private Map> getHeaders(HttpServletRequest request) {
+ Map> map = new LinkedHashMap<>();
+ Enumeration headerNames = request.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String headerName = headerNames.nextElement();
+ Enumeration headerValues = request.getHeaders(headerName);
+ map.put(headerName, Collections.list(headerValues));
+ }
+ return map;
+ }
+
+ private Map> getParams(HttpServletRequest request) {
+ Map> map = new LinkedHashMap<>();
+ for (Map.Entry entry : request.getParameterMap().entrySet()) {
+ map.put(entry.getKey(), Arrays.asList(entry.getValue()));
+ }
+ return map;
+ }
+}
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml
new file mode 100644
index 00000000..263a5699
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml
@@ -0,0 +1,12 @@
+dubbo:
+ registry:
+ # The Spring Cloud Dubbo's registry extension
+ address: spring-cloud://localhost
+# The traditional Dubbo's registry
+# address: zookeeper://127.0.0.1:2181
+server:
+ port: 0
+
+provider:
+ application:
+ name: spring-cloud-alibaba-dubbo-web-provider
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml
new file mode 100644
index 00000000..a86acd15
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml
@@ -0,0 +1,70 @@
+spring:
+ application:
+ name: spring-cloud-alibaba-dubbo-servlet-gateway
+ main:
+ allow-bean-definition-overriding: true
+
+
+ # default disable all
+ cloud:
+ nacos:
+ discovery:
+ enabled: false
+ register-enabled: false
+ zookeeper:
+ enabled: false
+ consul:
+ enabled: false
+
+eureka:
+ client:
+ enabled: false
+
+ribbon:
+ nacos:
+ enabled: false
+
+---
+spring:
+ profiles: nacos
+
+ cloud:
+ nacos:
+ discovery:
+ enabled: true
+ register-enabled: true
+ server-addr: 127.0.0.1:8848
+
+ribbon:
+ nacos:
+ enabled: true
+
+---
+spring:
+ profiles: eureka
+
+eureka:
+ client:
+ enabled: true
+ service-url:
+ defaultZone: http://127.0.0.1:8761/eureka/
+
+
+---
+spring:
+ profiles: zookeeper
+ cloud:
+ zookeeper:
+ enabled: true
+ connect-string: 127.0.0.1:2181
+
+
+---
+spring:
+ profiles: consul
+
+ cloud:
+ consul:
+ enabled: true
+ host: 127.0.0.1
+ port: 8500
\ No newline at end of file