顺利通过动态创建RequestMapping

This commit is contained in:
huangsimin 2019-06-26 15:39:49 +08:00
parent 53d572be7d
commit 9be72ebe6a
4 changed files with 145 additions and 169 deletions

View File

@ -2,36 +2,60 @@ package cn.ecpark.service.usergw.config;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.yaml.snakeyaml.Yaml;
import cn.ecpark.service.usergw.impl.http.Http2Dubbo;
import cn.ecpark.service.usergw.utils.Convert;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;
/**
* ConfigGateway
*/
@Component
@Controller
@Slf4j
public class ConfigGateway implements RouteDefinitionLocator {
List<MediaType> mediaTypes = new ArrayList<>();
// List<MediaType> mediaTypes = new ArrayList<>();
@Autowired
private ApplicationContext applicationContext;
@Autowired
private Http2Dubbo http2Dubbo;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
public Flux<RouteDefinition> getRouteDefinitions() {
// WebFluxConfigurationSupport a;
Object inputStream = null;
String[] gatewayConfigPathList = { "gateway.yml", "gateway.yaml", "Gateway.yml", "Gateway.yaml" };
for (String gatewayConfigPath : gatewayConfigPathList) {
@ -62,11 +86,113 @@ public class ConfigGateway implements RouteDefinitionLocator {
Map<String, Object> configDefault = (Map<String, Object>) configYaml.get("default");
Map<String, Object> configDubbo = (Map<String, Object>) configYaml.get("dubbo");
// ConfigProperties.createHttp2Dubbo(configDubbo);
return Flux.fromIterable(ConfigProperties.getConfigDefault(configDefault));
this.createHttp2Dubbo(configDubbo);
return Flux.fromIterable(this.getConfigDefault(configDefault));
}
}
return null;
// return Flux.fromIterable(it);
}
private List<RouteDefinition> getConfigDefault(Map<String, Object> configDefault) {
if (configDefault != null) {
List<RouteDefinition> RDList = new ArrayList<>();
List<FilterDefinition> filters = new ArrayList<>();
List<PredicateDefinition> predicates = new ArrayList<>();
// default-filters: 下的相关设置
Object unknownDefaultFilters = configDefault.get("default-filters");
if (unknownDefaultFilters != null) {
List<String> defaultFiltersYaml = (ArrayList<String>) unknownDefaultFilters;
for (String filterString : defaultFiltersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
Object unknownRoutes = configDefault.get("routes");
if (unknownRoutes != null) {
List<LinkedHashMap> routes = (ArrayList<LinkedHashMap>) unknownRoutes;
for (LinkedHashMap iter : routes) {
RouteDefinition rd = new RouteDefinition();
// 设置id
Object id = iter.get("id");
if (id != null) {
rd.setId((String) id);
}
// 设置uri
Object uri = iter.get("uri");
if (uri != null) {
rd.setUri(URI.create((String) uri));
}
// 设置uri
Object order = iter.get("order");
if (order != null) {
rd.setOrder((int) order);
}
// predicates: 下的相关属性
List<String> unknownPredicatesYaml = (ArrayList<String>) iter.get("predicates");
if (unknownPredicatesYaml != null) {
List<String> predicatesYaml = (ArrayList<String>) unknownPredicatesYaml;
for (String predicateString : predicatesYaml) {
predicates.add(new PredicateDefinition(predicateString));
}
}
// filters: 下的相关属性
List<String> unknownFiltersYaml = (ArrayList<String>) iter.get("filters");
if (unknownFiltersYaml != null) {
List<String> filtersYaml = (ArrayList<String>) unknownFiltersYaml;
for (String filterString : filtersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
rd.setPredicates(predicates);
rd.setFilters(filters);
RDList.add(rd);
}
return RDList;
}
}
return null;
}
private void createHttp2Dubbo(Map<String, Object> configDubbo) {
try {
RequestMappingHandlerMapping requestMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
// Method targetMethod = ReflectionUtils.findMethod(Http2Dubbo.class, "H2DTest", HttpServerRequest.class, HttpServerResponse.class); // 找到处理该路由的方法
requestMapping.registerMapping(RequestMappingInfo.paths("/test/xixi").methods(RequestMethod.POST).build(),
http2Dubbo, Http2Dubbo.class.getDeclaredMethod("H2DTest"));
// 引用远程服务
// try {
// ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); // 该实例很重量里面封装了所有与注册中心及服务提供方连接请缓存
// reference.setInterface("com.xxx.XxxService"); // 弱类型接口名
// reference.setVersion("2.0.0");
// reference.setGeneric(true); // 声明为泛化接口
// GenericService gs = reference.get();
} catch (Exception e) {
// TODO: 任何错误都直接终止退出
SpringApplication.exit(applicationContext);
}
// gs.$invoke(method, parameterTypes, args)
}
private static void callMethod(ReferenceConfig ref, String name, String params) throws Exception {
Method method = ref.getClass().getMethod("set" + Convert.firstUpperCase(name));
method.invoke(ref, method.getParameterTypes(), params);
}
}

View File

@ -1,161 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ecpark.service.usergw.config;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ReflectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.reactive.result.condition.PatternsRequestCondition;
import org.springframework.web.reactive.result.condition.RequestMethodsRequestCondition;
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import cn.ecpark.service.usergw.impl.http.Http2Dubbo;
import cn.ecpark.service.usergw.utils.Convert;
import lombok.extern.slf4j.Slf4j;
/**
* ConfigProperties
*/
@Validated
@Slf4j
public class ConfigProperties {
@Autowired
private static ApplicationContext applicationContext;
@Autowired
private static RequestMappingHandlerMapping requestMapping;
public static List<RouteDefinition> getConfigDefault(Map<String, Object> configDefault) {
if (configDefault != null) {
List<RouteDefinition> RDList = new ArrayList<>();
List<FilterDefinition> filters = new ArrayList<>();
List<PredicateDefinition> predicates = new ArrayList<>();
// default-filters: 下的相关设置
Object unknownDefaultFilters = configDefault.get("default-filters");
if (unknownDefaultFilters != null) {
List<String> defaultFiltersYaml = (ArrayList<String>) unknownDefaultFilters;
for (String filterString : defaultFiltersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
Object unknownRoutes = configDefault.get("routes");
if (unknownRoutes != null) {
List<LinkedHashMap> routes = (ArrayList<LinkedHashMap>) unknownRoutes;
for (LinkedHashMap iter : routes) {
RouteDefinition rd = new RouteDefinition();
// 设置id
Object id = iter.get("id");
if (id != null) {
rd.setId((String) id);
}
// 设置uri
Object uri = iter.get("uri");
if (uri != null) {
rd.setUri(URI.create((String) uri));
}
// 设置uri
Object order = iter.get("order");
if (order != null) {
rd.setOrder((int) order);
}
// predicates: 下的相关属性
List<String> unknownPredicatesYaml = (ArrayList<String>) iter.get("predicates");
if (unknownPredicatesYaml != null) {
List<String> predicatesYaml = (ArrayList<String>) unknownPredicatesYaml;
for (String predicateString : predicatesYaml) {
predicates.add(new PredicateDefinition(predicateString));
}
}
// filters: 下的相关属性
List<String> unknownFiltersYaml = (ArrayList<String>) iter.get("filters");
if (unknownFiltersYaml != null) {
List<String> filtersYaml = (ArrayList<String>) unknownFiltersYaml;
for (String filterString : filtersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
rd.setPredicates(predicates);
rd.setFilters(filters);
RDList.add(rd);
}
return RDList;
}
}
return null;
}
private static void callMethod(ReferenceConfig ref, String name, String params) throws Exception {
Method method = ref.getClass().getMethod("set" + Convert.firstUpperCase(name));
method.invoke(ref, method.getParameterTypes(), params);
}
public static void createHttp2Dubbo(Map<String, Object> configDubbo) {
Method targetMethod = ReflectionUtils.findMethod(Http2Dubbo.class, "12"); // 找到处理该路由的方法
requestMapping.registerMapping(RequestMappingInfo.paths("/test/xixi").methods(RequestMethod.POST).build(),
applicationContext,
targetMethod);
// 引用远程服务
try {
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); // 该实例很重量里面封装了所有与注册中心及服务提供方连接请缓存
reference.setInterface("com.xxx.XxxService"); // 弱类型接口名
reference.setVersion("2.0.0");
reference.setGeneric(true); // 声明为泛化接口
GenericService gs = reference.get();
} catch (Exception e) {
//TODO: 任何错误都直接终止退出
SpringApplication.exit(applicationContext);
}
// gs.$invoke(method, parameterTypes, args)
}
}

View File

@ -1,12 +1,23 @@
package cn.ecpark.service.usergw.impl.http;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Http2Dubbo
*/
@RestController
@Controller
public class Http2Dubbo {
@ResponseBody
public String H2DTest() {
//Do clever stuff here
return "123";
// return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -14,5 +14,5 @@ dubbo:
- id: test
path: /dubbo/hello
interface: com.xxx.xxx
version: 1
version: 2.0.0