restful调用优化

pull/1/head
tanghc 5 years ago
parent 6b3b38e058
commit 58cd959e01
  1. 64
      doc/docs/_sidebar.md
  2. 23
      doc/docs/files/10100_提供restful接口.md
  3. 29
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java
  4. 12
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java
  5. 23
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/EnvironmentContext.java
  6. 37
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/EnvironmentKeys.java

@ -1,34 +1,34 @@
* [首页](/?t=1570680160879) * [首页](/?t=1571107529420)
* 开发文档 * 开发文档
* [快速体验](files/10010_快速体验.md?t=1570680160882) * [快速体验](files/10010_快速体验.md?t=1571107529423)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1570680160897) * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1571107529447)
* [新增接口](files/10020_新增接口.md?t=1570680160897) * [新增接口](files/10020_新增接口.md?t=1571107529447)
* [开发流程](files/10021_开发流程.md?t=1570680160897) * [开发流程](files/10021_开发流程.md?t=1571107529447)
* [业务参数校验](files/10030_业务参数校验.md?t=1570680160897) * [业务参数校验](files/10030_业务参数校验.md?t=1571107529447)
* [错误处理](files/10040_错误处理.md?t=1570680160897) * [错误处理](files/10040_错误处理.md?t=1571107529447)
* [编写文档](files/10041_编写文档.md?t=1570680160898) * [编写文档](files/10041_编写文档.md?t=1571107529447)
* [接口交互详解](files/10050_接口交互详解.md?t=1570680160898) * [接口交互详解](files/10050_接口交互详解.md?t=1571107529448)
* [easyopen支持](files/10070_easyopen支持.md?t=1570680160898) * [easyopen支持](files/10070_easyopen支持.md?t=1571107529448)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1570680160898) * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1571107529448)
* [ISV管理](files/10085_ISV管理.md?t=1570680160898) * [ISV管理](files/10085_ISV管理.md?t=1571107529448)
* [自定义返回结果](files/10087_自定义返回结果.md?t=1570680160898) * [自定义返回结果](files/10087_自定义返回结果.md?t=1571107529448)
* [自定义过滤器](files/10088_自定义过滤器.md?t=1570680160898) * [自定义过滤器](files/10088_自定义过滤器.md?t=1571107529448)
* [路由授权](files/10090_路由授权.md?t=1570680160898) * [路由授权](files/10090_路由授权.md?t=1571107529448)
* [接口限流](files/10092_接口限流.md?t=1570680160899) * [接口限流](files/10092_接口限流.md?t=1571107529448)
* [监控日志](files/10093_监控日志.md?t=1570680160899) * [监控日志](files/10093_监控日志.md?t=1571107529448)
* [SDK开发](files/10095_SDK开发.md?t=1570680160899) * [SDK开发](files/10095_SDK开发.md?t=1571107529449)
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1570680160899) * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1571107529449)
* [应用授权](files/10097_应用授权.md?t=1570680160899) * [应用授权](files/10097_应用授权.md?t=1571107529449)
* [提供restful接口](files/10100_提供restful接口.md?t=1570680160899) * [提供restful接口](files/10100_提供restful接口.md?t=1571107529449)
* [文件上传](files/10104_文件上传.md?t=1570680160899) * [文件上传](files/10104_文件上传.md?t=1571107529449)
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1570680160899) * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1571107529449)
* [预发布灰度发布](files/10110_预发布灰度发布.md?t=1570680160899) * [预发布灰度发布](files/10110_预发布灰度发布.md?t=1571107529449)
* [动态修改请求参数](files/10111_动态修改请求参数.md?t=1570680160899) * [动态修改请求参数](files/10111_动态修改请求参数.md?t=1571107529450)
* [使用eureka](files/10112_使用eureka.md?t=1570680160899) * [使用eureka](files/10112_使用eureka.md?t=1571107529450)
* [扩展其它注册中心](files/10113_扩展其它注册中心.md?t=1570680160900) * [扩展其它注册中心](files/10113_扩展其它注册中心.md?t=1571107529450)
* 原理分析 * 原理分析
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1570680160900) * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1571107529450)
* [原理分析之如何存储路由](files/90011_原理分析之如何存储路由.md?t=1570680160900) * [原理分析之如何存储路由](files/90011_原理分析之如何存储路由.md?t=1571107529450)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1570680160900) * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1571107529450)
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1570680160900) * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1571107529450)
* [常见问题](files/90100_常见问题.md?t=1570680160900) * [常见问题](files/90100_常见问题.md?t=1571107529450)

@ -11,11 +11,18 @@
sop.restful.enable=true sop.restful.enable=true
``` ```
- 前端app请求网关 - 前端app请求网关(`2.4.1+之后有变动`)
请求格式`http://ip:port/rest/your_path`,其中`http://ip:port/rest/`为固定部分,后面跟微服务请求路径。 请求格式:
注意:为了确保各个微服务路径不冲突,必须保证类上方定义的`@RequestMapping`内容唯一,不与其它微服务重复。 **2.4.1版本之前:** `http://ip:port/rest/your_path`,其中`http://ip:port/rest/`为固定部分,后面跟微服务请求路径。
**2.4.1之后:** `http://ip:port/rest/服务id/your_path`,其中`http://ip:port/rest/`为固定部分,后面跟微服务请求路径。
**注意,`2.4.1`开始多了一个服务id作为区分,这样做是为了避免各微服务之间url冲突,假如两个微服务都有一个叫`/getItems`这样的接口
那么调用`http://ip:port/rest/getItems`接口网关无法做出正确的路由,虽然可以在代码上进行规范,为了防止万一,还是强行加上了,避免采坑**
> 可在微服务端指定一个配置:`sop.restful.prefix=xxx`。请求路径将变成:`http://ip:port/rest/xxx/your_path`
下面是一个微服务的接口例子 下面是一个微服务的接口例子
@ -34,9 +41,9 @@ public class TraditionalWebappController {
} }
``` ```
这是一个`食品服务`例子,假设网关ip为10.0.1.11,端口8081;食品服务ip为10.0.1.22,端口2222 这是一个`食品服务`例子,serviceId为`food-service`,假设网关ip为10.0.1.11,端口8081;食品服务ip为10.0.1.22,端口2222
1. 网关访问:`http://10.0.1.11:8081/rest/food/getFoodById?id=2` 1. 网关访问:`http://10.0.1.11:8081/rest/food-service/food/getFoodById?id=2`
2. 本地访问:`http://10.0.1.22:2222/food/getFoodById/?id=2` 2. 本地访问:`http://10.0.1.22:2222/food/getFoodById/?id=2`
@ -63,7 +70,7 @@ const client = axios.create({
const RequestUtil = { const RequestUtil = {
/** /**
* 请求接口 * 请求接口
* @param url 请求路径,如http://localhost:8081/rest/food/getFoodById * @param url 请求路径,如http://localhost:8081/rest/food-service/food/getFoodById
* @param data 请求数据,json格式 * @param data 请求数据,json格式
* @param callback 成功回调 * @param callback 成功回调
* @param errorCallback 失败回调 * @param errorCallback 失败回调
@ -101,7 +108,7 @@ jQuery版本如下:
var RequestUtil = { var RequestUtil = {
/** /**
* 请求接口 * 请求接口
* @param url 请求路径,如http://localhost:8081/rest/food/getFoodById * @param url 请求路径,如http://localhost:8081/rest/food-service/food/getFoodById
* @param data 请求数据,json格式 * @param data 请求数据,json格式
* @param callback 成功回调 * @param callback 成功回调
* @param errorCallback 失败回调 * @param errorCallback 失败回调
@ -139,7 +146,7 @@ $(function () {
id: 1 id: 1
,name: '葫芦娃' ,name: '葫芦娃'
} }
RequestUtil.post('http://localhost:8081/rest/food/getFoodById', data, function (result) { RequestUtil.post('http://localhost:8081/rest/food-service/food/getFoodById', data, function (result) {
console.log(result) console.log(result)
}); });
}) })

@ -2,14 +2,15 @@ package com.gitee.sop.servercommon.configuration;
import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.interceptor.ServiceContextInterceptor; import com.gitee.sop.servercommon.interceptor.ServiceContextInterceptor;
import com.gitee.sop.servercommon.manager.EnvironmentContext;
import com.gitee.sop.servercommon.manager.ServiceRouteController; import com.gitee.sop.servercommon.manager.ServiceRouteController;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping; import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import com.gitee.sop.servercommon.message.ServiceErrorFactory; import com.gitee.sop.servercommon.message.ServiceErrorFactory;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -25,8 +26,7 @@ import java.util.List;
* @author tanghc * @author tanghc
*/ */
@Slf4j @Slf4j
public class BaseServiceConfiguration extends WebMvcConfigurationSupport public class BaseServiceConfiguration extends WebMvcConfigurationSupport {
implements ApplicationRunner {
public BaseServiceConfiguration() { public BaseServiceConfiguration() {
ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror"); ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror");
@ -34,6 +34,9 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport
private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping(); private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping();
@Autowired
private Environment environment;
@Override @Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) { protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry); super.addResourceHandlers(registry);
@ -85,20 +88,11 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport
@PostConstruct @PostConstruct
public final void after() { public final void after() {
log.info("-----spring容器加载完毕-----"); log.info("-----spring容器加载完毕-----");
EnvironmentContext.setEnvironment(environment);
initMessage(); initMessage();
doAfter(); doAfter();
} }
/**
* springboot启动完成后执行
* @param args 启动参数
* @throws Exception 出错异常
*/
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("-----服务器启动完毕-----");
this.onStartup(args);
}
/** /**
* spring容器加载完毕后执行 * spring容器加载完毕后执行
@ -107,13 +101,6 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport
} }
/**
* 启动完毕后执行
* @param args
*/
protected void onStartup(ApplicationArguments args) {
}
protected void initMessage() { protected void initMessage() {
ServiceErrorFactory.initMessageSource(ServiceConfig.getInstance().getI18nModules()); ServiceErrorFactory.initMessageSource(ServiceConfig.getInstance().getI18nModules());

@ -7,6 +7,7 @@ import com.gitee.sop.servercommon.mapping.ApiMappingInfo;
import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition; import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition;
import com.gitee.sop.servercommon.mapping.RouteUtil; import com.gitee.sop.servercommon.mapping.RouteUtil;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
@ -91,11 +92,20 @@ public class ApiMetaBuilder {
if (!ServiceContext.getCurrentContext().getBoolean(ServiceContext.RESTFUL_KEY, false)) { if (!ServiceContext.getCurrentContext().getBoolean(ServiceContext.RESTFUL_KEY, false)) {
return null; return null;
} }
// 如果是restful服务
String path = patterns.iterator().next(); String path = patterns.iterator().next();
if (path.contains("$") || isIgnorePattern(path)) { if (path.contains("$") || isIgnorePattern(path)) {
return null; return null;
} }
ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(path, path, ""); String name = path;
String prefix = EnvironmentKeys.SOP_RESTFUL_PREFIX.getValue();
if (StringUtils.isEmpty(prefix)) {
prefix = EnvironmentKeys.SPRING_APPLICATION_NAME.getValue();
}
if (StringUtils.hasText(prefix)) {
name = "/" + prefix + "/" + StringUtils.trimLeadingCharacter(path, '/');
}
ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(name, path, "");
apiMeta.setIgnoreValidate(BooleanUtils.toInteger(true)); apiMeta.setIgnoreValidate(BooleanUtils.toInteger(true));
apiMeta.setMergeResult(BooleanUtils.toInteger(false)); apiMeta.setMergeResult(BooleanUtils.toInteger(false));
apiMeta.setPermission(BooleanUtils.toInteger(false)); apiMeta.setPermission(BooleanUtils.toInteger(false));

@ -0,0 +1,23 @@
package com.gitee.sop.servercommon.manager;
import org.springframework.core.env.Environment;
/**
* @author tanghc
*/
public class EnvironmentContext {
private static Environment environment;
public static Environment getEnvironment() {
return environment;
}
public static void setEnvironment(Environment environment) {
EnvironmentContext.environment = environment;
}
public static String getValue(String key, String defaultValue) {
return environment.getProperty(key, defaultValue);
}
}

@ -0,0 +1,37 @@
package com.gitee.sop.servercommon.manager;
import javax.annotation.Nullable;
public enum EnvironmentKeys {
SPRING_PROFILES_ACTIVE("spring.profiles.active", "default"),
/**
* spring.application.name
*/
SPRING_APPLICATION_NAME("spring.application.name"),
/**
* sop.restful.prefix=xxx指定web开发模式前缀不指定默认为service-id
*/
SOP_RESTFUL_PREFIX("sop.restful.prefix");
private String key;
private String defaultValue;
public String getKey() {
return key;
}
EnvironmentKeys(String key) {
this.key = key;
}
EnvironmentKeys(String key, String defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
}
@Nullable
public String getValue() {
return EnvironmentContext.getValue(key, defaultValue);
}
}
Loading…
Cancel
Save