diff --git a/changelog.md b/changelog.md index 273ce30e..bb3892eb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # changelog +## 1.13.1 + +- 支持json方式请求(application/json) ## 1.13.0 diff --git a/doc/docs/_sidebar.md b/doc/docs/_sidebar.md index 88f0f8b6..dd8bf3d4 100644 --- a/doc/docs/_sidebar.md +++ b/doc/docs/_sidebar.md @@ -1,32 +1,32 @@ -* [首页](/?t=1563439736156) +* [首页](/?t=1563956863130) * 开发文档 - * [快速体验](files/10010_快速体验.md?t=1563439736157) - * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1563439736174) - * [新增接口](files/10020_新增接口.md?t=1563439736174) - * [业务参数校验](files/10030_业务参数校验.md?t=1563439736174) - * [错误处理](files/10040_错误处理.md?t=1563439736174) - * [编写文档](files/10041_编写文档.md?t=1563439736174) - * [接口交互详解](files/10050_接口交互详解.md?t=1563439736174) - * [easyopen支持](files/10070_easyopen支持.md?t=1563439736175) - * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1563439736175) - * [ISV管理](files/10085_ISV管理.md?t=1563439736175) - * [自定义路由](files/10086_自定义路由.md?t=1563439736175) - * [路由授权](files/10090_路由授权.md?t=1563439736175) - * [接口限流](files/10092_接口限流.md?t=1563439736175) - * [监控日志](files/10093_监控日志.md?t=1563439736175) - * [SDK开发](files/10095_SDK开发.md?t=1563439736175) - * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1563439736176) - * [应用授权](files/10097_应用授权.md?t=1563439736176) - * [更改数据节点名称](files/10099_更改数据节点名称.md?t=1563439736176) - * [对接前端](files/10100_对接前端.md?t=1563439736176) - * [自定义过滤器](files/10102_自定义过滤器.md?t=1563439736176) - * [文件上传](files/10104_文件上传.md?t=1563439736176) - * [nacos注册中心](files/10106_nacos注册中心.md?t=1563439736176) - * [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1563439736176) - * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1563439736176) + * [快速体验](files/10010_快速体验.md?t=1563956863132) + * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1563956863153) + * [新增接口](files/10020_新增接口.md?t=1563956863153) + * [业务参数校验](files/10030_业务参数校验.md?t=1563956863153) + * [错误处理](files/10040_错误处理.md?t=1563956863153) + * [编写文档](files/10041_编写文档.md?t=1563956863153) + * [接口交互详解](files/10050_接口交互详解.md?t=1563956863153) + * [easyopen支持](files/10070_easyopen支持.md?t=1563956863154) + * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1563956863154) + * [ISV管理](files/10085_ISV管理.md?t=1563956863154) + * [自定义路由](files/10086_自定义路由.md?t=1563956863154) + * [路由授权](files/10090_路由授权.md?t=1563956863154) + * [接口限流](files/10092_接口限流.md?t=1563956863154) + * [监控日志](files/10093_监控日志.md?t=1563956863154) + * [SDK开发](files/10095_SDK开发.md?t=1563956863154) + * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1563956863154) + * [应用授权](files/10097_应用授权.md?t=1563956863155) + * [更改数据节点名称](files/10099_更改数据节点名称.md?t=1563956863155) + * [传统web开发](files/10100_传统web开发.md?t=1563956863155) + * [自定义过滤器](files/10102_自定义过滤器.md?t=1563956863155) + * [文件上传](files/10104_文件上传.md?t=1563956863155) + * [nacos注册中心](files/10106_nacos注册中心.md?t=1563956863155) + * [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1563956863155) + * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1563956863155) * 原理分析 - * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1563439736177) - * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1563439736177) - * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1563439736177) - * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1563439736177) - * [常见问题](files/90100_常见问题.md?t=1563439736177) + * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1563956863156) + * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1563956863156) + * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1563956863156) + * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1563956863156) + * [常见问题](files/90100_常见问题.md?t=1563956863156) diff --git a/doc/docs/files/10100_对接前端.md b/doc/docs/files/10100_传统web开发.md similarity index 81% rename from doc/docs/files/10100_对接前端.md rename to doc/docs/files/10100_传统web开发.md index 8d39a37b..e6283544 100644 --- a/doc/docs/files/10100_对接前端.md +++ b/doc/docs/files/10100_传统web开发.md @@ -1,41 +1,40 @@ -# 对接前端 +# 传统web开发 -开放平台一般对接服务端应用,开发者使用SDK来调用接口。 -理论上来说,只要是客户端程序,都可以调用网关接口。因此,同样可以对接前端应用(H5、小程序、App)。 +本篇介绍如何使用SOP进行传统web服务开发,即对接前端应用(H5、小程序、App)。 -针对H5页面,配置方式如下: - -- 网关关闭签名校验。`ApiConfig.getInstance().setIgnoreValidate(true);` - -由于是网页调用接口,把秘钥放在前端意义不大,干脆直接关闭签名校验。 - -- 设置统一的数据节点 +- 网关ZuulConfig继承WebappZuulConfiguration类 ```java @Configuration -public class ZuulConfig extends AlipayZuulConfiguration { +public class ZuulConfig extends WebappZuulConfiguration { static { - ... - ApiConfig.getInstance().setIgnoreValidate(true); - ApiConfig.getInstance().setDataNameBuilder(new CustomDataNameBuilder()); - ... + new ManagerInitializer(); } } ``` -设置后,网关统一的返回结果如下: +设置完毕,网关不在进行签名验证,网关统一的返回结果如下: ```json { "result": { ... - }, - "sign": "xxxxx" + } } ``` +- 微服务OpenServiceConfig继承WebappServiceConfiguration类 + +```java +public class OpenServiceConfig extends WebappServiceConfiguration { + ... +} +``` + +其它内容不变 + - 封装请求工具【可选】 封装请求,方便调用,针对vue的封装如下: diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index cb1305df..034e5764 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -30,7 +30,7 @@ com.gitee.sop sop-registry-api - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT diff --git a/sop-common/pom.xml b/sop-common/pom.xml index 706060c4..1d079bdd 100644 --- a/sop-common/pom.xml +++ b/sop-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT pom diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 3223c94d..59d171c4 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -5,11 +5,11 @@ com.gitee.sop sop-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT ../pom.xml sop-gateway-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT jar sop-gateway-common diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java index edbafae7..d48e3b9b 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java @@ -1,5 +1,7 @@ package com.gitee.sop.gatewaycommon.util; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @@ -35,6 +37,9 @@ public class RequestUtil { public static final String MULTIPART = "multipart/"; private static final String UTF8 = "UTF-8"; + private static final String IP_UNKNOWN = "unknown"; + private static final String IP_LOCAL = "127.0.0.1"; + private static final int IP_LEN = 15; /** * 将get类型的参数转换成map, @@ -114,6 +119,31 @@ public class RequestUtil { return params; } + /** + * 转换json请求到Map, + * @param request 请求类型为application/json的Request + * @return 返回Map + */ + public static Map convertJsonRequestToMap(HttpServletRequest request) { + try { + String text = getText(request); + JSONObject parseObject = JSON.parseObject(text); + Map params = new HashMap<>(parseObject.size()); + for (Map.Entry entry : parseObject.entrySet()) { + params.put(entry.getKey(), String.valueOf(entry.getValue())); + } + return params; + } catch (IOException e) { + log.error("解析json请求失败", e); + return Collections.emptyMap(); + } + } + + /** + * 是否是文件上传请求 + * @param request 请求 + * @return true:是 + */ public static boolean isMultipart(HttpServletRequest request) { String contentType = request.getContentType(); // Don't use this filter on GET method @@ -130,29 +160,32 @@ public class RequestUtil { public static String getIP(HttpServletRequest request) { String ipAddress = request.getHeader("x-forwarded-for"); - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } - - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } - - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); - if ("127.0.0.1".equals(ipAddress)) { + if (IP_LOCAL.equals(ipAddress)) { + // 根据网卡取本机配置的IP try { InetAddress inet = InetAddress.getLocalHost(); ipAddress = inet.getHostAddress(); - } catch (UnknownHostException var3) { + } catch (UnknownHostException e) { + // ignore } } - } - if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(",") > 0) { - ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > IP_LEN) { + if (ipAddress.indexOf(",") > 0) { + ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); + } + } return ipAddress; } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java index b961ced1..b73c0ebf 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java @@ -6,6 +6,7 @@ import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter; import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter; +import com.gitee.sop.gatewaycommon.zuul.filter.PreHttpServletRequestWrapperFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter; import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt; @@ -43,6 +44,11 @@ public class BaseZuulConfiguration extends AbstractConfiguration { return zuulRouteRepository; } + @Bean + PreHttpServletRequestWrapperFilter preHttpServletRequestWrapperFilter() { + return new PreHttpServletRequestWrapperFilter(); + } + @Bean FormBodyWrapperFilterExt formBodyWrapperFilterExt() { return new FormBodyWrapperFilterExt(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java new file mode 100644 index 00000000..916ba2ed --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java @@ -0,0 +1,18 @@ +package com.gitee.sop.gatewaycommon.zuul.configuration; + +import com.gitee.sop.gatewaycommon.bean.ApiConfig; +import com.gitee.sop.gatewaycommon.result.CustomDataNameBuilder; + +/** + * 支持传统webapp开发,没有签名验证 + * + * @author tanghc + */ +public class WebappZuulConfiguration extends BaseZuulConfiguration { + + static { + ApiConfig.getInstance().setIgnoreValidate(true); + ApiConfig.getInstance().setDataNameBuilder(new CustomDataNameBuilder()); + ApiConfig.getInstance().setShowReturnSign(false); + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/BaseZuulFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/BaseZuulFilter.java index ca0ac2c8..29b97e4f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/BaseZuulFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/BaseZuulFilter.java @@ -14,6 +14,12 @@ public abstract class BaseZuulFilter extends ZuulFilter { protected Logger log = LoggerFactory.getLogger(getClass()); + public static final int HTTP_SERVLET_REQUEST_WRAPPER_FILTER_ORDER = -2000; + + public static final int SERVLET_30_WRAPPER_FILTER_ORDER = HTTP_SERVLET_REQUEST_WRAPPER_FILTER_ORDER + 1; + + public static final int FORM_BODY_WRAPPER_FILTER_ORDER = SERVLET_30_WRAPPER_FILTER_ORDER + 1; + /** 签名验证过滤 */ public static final int PRE_VALIDATE_FILTER_ORDER = -1000; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/FormBodyWrapperFilterExt.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/FormBodyWrapperFilterExt.java index 5dcc9593..96fce214 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/FormBodyWrapperFilterExt.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/FormBodyWrapperFilterExt.java @@ -1,26 +1,25 @@ package com.gitee.sop.gatewaycommon.zuul.filter; -import com.gitee.sop.gatewaycommon.util.RequestUtil; -import com.netflix.zuul.context.RequestContext; import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter; -import javax.servlet.http.HttpServletRequest; - /** * @author tanghc */ public class FormBodyWrapperFilterExt extends FormBodyWrapperFilter { - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - // 如果是文件上传请求,不需要包装 - if (RequestUtil.isMultipart(request)) { - return false; - } else { - return super.shouldFilter(); - } + public int filterOrder() { + return BaseZuulFilter.FORM_BODY_WRAPPER_FILTER_ORDER; } + + // @Override +// public boolean shouldFilter() { +// RequestContext ctx = RequestContext.getCurrentContext(); +// HttpServletRequest request = ctx.getRequest(); +// // 如果是文件上传请求,不需要包装 +// if (RequestUtil.isMultipart(request)) { +// return false; +// } else { +// return super.shouldFilter(); +// } +// } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreHttpServletRequestWrapperFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreHttpServletRequestWrapperFilter.java new file mode 100644 index 00000000..3c1ed38a --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreHttpServletRequestWrapperFilter.java @@ -0,0 +1,31 @@ +package com.gitee.sop.gatewaycommon.zuul.filter; + +import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.exception.ZuulException; +import com.netflix.zuul.http.HttpServletRequestWrapper; + +import javax.servlet.http.HttpServletRequest; + +/** + * 包装一下Request,使得request.getInputStream()方法可以调用多次 + * @author tanghc + */ +public class PreHttpServletRequestWrapperFilter extends BaseZuulFilter { + @Override + protected FilterType getFilterType() { + return FilterType.PRE; + } + + @Override + protected int getFilterOrder() { + return HTTP_SERVLET_REQUEST_WRAPPER_FILTER_ORDER; + } + + @Override + protected Object doRun(RequestContext requestContext) throws ZuulException { + HttpServletRequest request = requestContext.getRequest(); + HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); + requestContext.setRequest(wrapper); + return null; + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/Servlet30WrapperFilterExt.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/Servlet30WrapperFilterExt.java index e5973e00..336a2ed1 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/Servlet30WrapperFilterExt.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/Servlet30WrapperFilterExt.java @@ -1,24 +1,25 @@ package com.gitee.sop.gatewaycommon.zuul.filter; -import com.gitee.sop.gatewaycommon.util.RequestUtil; -import com.netflix.zuul.context.RequestContext; import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; -import javax.servlet.http.HttpServletRequest; - /** * @author tanghc */ public class Servlet30WrapperFilterExt extends Servlet30WrapperFilter { @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - // 如果是文件上传请求,不需要包装 - if (RequestUtil.isMultipart(request)) { - return false; - } else { - return super.shouldFilter(); - } + public int filterOrder() { + return BaseZuulFilter.SERVLET_30_WRAPPER_FILTER_ORDER; } + + // @Override +// public boolean shouldFilter() { +// RequestContext ctx = RequestContext.getCurrentContext(); +// HttpServletRequest request = ctx.getRequest(); +// // 如果是文件上传请求,不需要包装 +// if (RequestUtil.isMultipart(request)) { +// return false; +// } else { +// return super.shouldFilter(); +// } +// } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java index b3bf1670..b219f8bf 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java @@ -1,21 +1,15 @@ package com.gitee.sop.gatewaycommon.zuul.param; import com.gitee.sop.gatewaycommon.bean.SopConstants; -import com.gitee.sop.gatewaycommon.message.ErrorEnum; import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.BaseParamBuilder; import com.gitee.sop.gatewaycommon.util.RequestUtil; import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ServletInputStreamWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.commons.io.IOUtils; import org.springframework.http.MediaType; -import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; -import java.io.IOException; import java.util.Map; /** @@ -33,32 +27,24 @@ public class ZuulParamBuilder extends BaseParamBuilder { @Override public Map buildRequestParams(RequestContext ctx) { HttpServletRequest request = ctx.getRequest(); - Map params = null; - + Map params; if (GET.equalsIgnoreCase(request.getMethod())) { params = RequestUtil.convertRequestParamsToMap(request); } else { String contentType = request.getContentType(); - if (contentType == null) { contentType = ""; } - contentType = contentType.toLowerCase(); - // json或者纯文本形式 if (contentType.contains(CONTENT_TYPE_JSON) || contentType.contains(CONTENT_TYPE_TEXT)) { - throw ErrorEnum.ISV_INVALID_CONTENT_TYPE.getErrorMeta().getException(); + params = RequestUtil.convertJsonRequestToMap(request); } else if (ServletFileUpload.isMultipartContent(request)) { - MultipartRequestWrapper wrapper = new MultipartRequestWrapper(request); - ctx.setRequest(wrapper); - ctx.getZuulRequestHeaders().put("content-type", wrapper.getContentType()); - params = RequestUtil.convertMultipartRequestToMap(wrapper); + params = RequestUtil.convertMultipartRequestToMap(request); } else { params = RequestUtil.convertRequestParamsToMap(request); } } - return params; } @@ -78,45 +64,4 @@ public class ZuulParamBuilder extends BaseParamBuilder { return apiParam; } - public static class MultipartRequestWrapper extends HttpServletRequestWrapper { - private HttpServletRequest request; - - private volatile byte[] contentData; - - private MediaType contentType; - - private int contentLength; - - public MultipartRequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - try { - this.contentType = MediaType.valueOf(this.request.getContentType()); - byte[] input = IOUtils.toByteArray(request.getInputStream()); - this.contentData = input; - this.contentLength = input.length; - } catch (Exception e) { - throw new IllegalStateException("Cannot convert form data", e); - } - } - - @Override - public String getContentType() { - return this.contentType.toString(); - } - - @Override - public int getContentLength() { - if (super.getContentLength() <= 0) { - return super.getContentLength(); - } - return this.contentLength; - } - - @Override - public ServletInputStream getInputStream() throws IOException { - return new ServletInputStreamWrapper(this.contentData); - } - } - } diff --git a/sop-common/sop-registry-api/pom.xml b/sop-common/sop-registry-api/pom.xml index 101cc5b9..00c4191c 100644 --- a/sop-common/sop-registry-api/pom.xml +++ b/sop-common/sop-registry-api/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-registry-api - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT UTF-8 diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index a7a8309d..a0818acb 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -6,11 +6,11 @@ com.gitee.sop sop-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT ../pom.xml sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT jar sop-service-common diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/AlipayServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/AlipayServiceConfiguration.java index a1748613..e35f9237 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/AlipayServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/AlipayServiceConfiguration.java @@ -33,7 +33,6 @@ public class AlipayServiceConfiguration extends BaseServiceConfiguration { protected void doAfter() { super.doAfter(); SopHandlerMethodArgumentResolver sopHandlerMethodArgumentResolver = ServiceConfig.getInstance().getMethodArgumentResolver(); - List defaultArgumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers(); - sopHandlerMethodArgumentResolver.setResolvers(defaultArgumentResolvers); + sopHandlerMethodArgumentResolver.setRequestMappingHandlerAdapter(requestMappingHandlerAdapter); } } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/WebappServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/WebappServiceConfiguration.java new file mode 100644 index 00000000..eac13717 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/WebappServiceConfiguration.java @@ -0,0 +1,14 @@ +package com.gitee.sop.servercommon.configuration; + +import com.gitee.sop.servercommon.bean.ServiceConfig; + +/** + * 通用web + * @author tanghc + */ +public class WebappServiceConfiguration extends BaseServiceConfiguration { + static { + // 默认版本号为1.0 + ServiceConfig.getInstance().setDefaultVersion("1.0"); + } +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java index db470b77..214af30c 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java @@ -24,6 +24,9 @@ import java.util.Set; @Getter public class DefaultRequestMappingEvent implements RequestMappingEvent { + /** 接口名规则:允许字母、数字、点、下划线 */ + private static final String REGEX_API_NAME = "^[a-zA-Z0-9\\.\\_\\-]+$"; + private ApiMetaManager apiMetaManager; private Environment environment; @@ -85,6 +88,7 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent { if (name == null) { name = buildName(path); } + this.checkApiName(name); ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(name, path, version); apiMeta.setIgnoreValidate(BooleanUtils.toInteger(apiMappingInfo.isIgnoreValidate())); apiMeta.setMergeResult(BooleanUtils.toInteger(apiMappingInfo.isMergeResult())); @@ -94,6 +98,12 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent { return null; } + protected void checkApiName(String name) { + if (!name.matches(REGEX_API_NAME)) { + throw new IllegalArgumentException("接口名称只允许【字母、数字、点(.)、下划线(_)、减号(-)】,错误接口:" + name); + } + } + protected String buildName(String path) { return MappingUtil.buildApiName(path); } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java index 2807e123..09a01b63 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java @@ -32,7 +32,7 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { * zookeeper存放接口路由信息的根目录 */ public static final String SOP_SERVICE_ROUTE_PATH = ServiceConstants.SOP_SERVICE_ROUTE_PATH; - public static final String PATH_START_CHAR = "/"; + public static final String PATH_SPLIT = "/"; private final String routeRootPath = SOP_SERVICE_ROUTE_PATH; @@ -60,6 +60,7 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { */ protected void uploadServiceId(Environment environment) { try { + this.checkZookeeperNode(serviceId, "serviceId(" + serviceId + ")不能有斜杠字符'/'"); ServiceRouteInfo serviceRouteInfo = this.buildServiceRouteInfo(); // 保存路径 String savePath = routeRootPath + "/" + serviceId; @@ -109,9 +110,11 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { protected GatewayRouteDefinition buildGatewayRouteDefinition(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { GatewayRouteDefinition gatewayRouteDefinition = new GatewayRouteDefinition(); + String routeId = apiMeta.fetchNameVersion(); + this.checkZookeeperNode(routeId, "接口定义(" + routeId + ")不能有斜杠字符'/'"); // 唯一id规则:接口名 + 版本号 BeanUtils.copyProperties(apiMeta, gatewayRouteDefinition); - gatewayRouteDefinition.setId(apiMeta.fetchNameVersion()); + gatewayRouteDefinition.setId(routeId); gatewayRouteDefinition.setFilters(Collections.emptyList()); String uri = this.buildUri(serviceApiInfo, apiMeta); String path = this.buildServletPath(serviceApiInfo, apiMeta); @@ -129,8 +132,8 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { if (servletPath == null) { servletPath = ""; } - if (!servletPath.startsWith(PATH_START_CHAR)) { - servletPath = PATH_START_CHAR + servletPath; + if (!servletPath.startsWith(PATH_SPLIT)) { + servletPath = PATH_SPLIT + servletPath; } return servletPath; } @@ -181,11 +184,17 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { List routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); for (GatewayRouteDefinition routeDefinition : routeDefinitionList) { // 父目录/子目录 - String savePath = parentPath + PATH_START_CHAR + routeDefinition.getId(); + String savePath = parentPath + PATH_SPLIT + routeDefinition.getId(); String routeDefinitionJson = JSON.toJSONString(routeDefinition); log.info("上传路由配置到zookeeper,路径:{},路由数据:{}", savePath, routeDefinitionJson); this.zookeeperTool.createOrUpdateData(savePath, routeDefinitionJson); } } + private void checkZookeeperNode(String path, String errorMsg) { + if (path.contains(PATH_SPLIT)) { + throw new IllegalArgumentException(errorMsg); + } + } + } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java index 6ff16e64..ddf3d09b 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java @@ -11,9 +11,9 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,16 +25,15 @@ import java.util.concurrent.ConcurrentHashMap; */ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { - private final Map argumentResolverCache = - new ConcurrentHashMap<>(256); + private final Map argumentResolverCache = new ConcurrentHashMap<>(256); - private final ParamValidator paramValidator = new ServiceParamValidator(); + private ParamValidator paramValidator = new ServiceParamValidator(); - private List argumentResolvers = Collections.emptyList(); + private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @Override - public void setResolvers(List resolvers) { - this.argumentResolvers = resolvers; + public void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) { + this.requestMappingHandlerAdapter = requestMappingHandlerAdapter; } @Override @@ -61,18 +60,19 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { } } + /** * 获取参数对象,将request中的参数绑定到实体对象中去 * * @param methodParameter * @param nativeWebRequest - * @return + * @return 没有返回null */ protected Object getParamObject(MethodParameter methodParameter, NativeWebRequest nativeWebRequest) { String bizContent = nativeWebRequest.getParameter(ParamNames.BIZ_CONTENT_NAME); - Class parameterType = methodParameter.getParameterType(); Object bizObj = null; if (bizContent != null) { + Class parameterType = methodParameter.getParameterType(); bizObj = JSON.parseObject(bizContent, parameterType); } this.bindUploadFile(bizObj, nativeWebRequest); @@ -80,7 +80,7 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { } /** - * 将文件绑定到 + * 将上传文件对象绑定到属性中 * * @param bizObj 业务参数 * @param nativeWebRequest @@ -89,9 +89,9 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { if (bizObj == null) { return; } - Object nativeRequest = nativeWebRequest.getNativeRequest(); - if (nativeRequest instanceof StandardMultipartHttpServletRequest) { - StandardMultipartHttpServletRequest request = (StandardMultipartHttpServletRequest) nativeRequest; + if (this.isMultipartRequest(nativeWebRequest)) { + Object nativeRequest = nativeWebRequest.getNativeRequest(); + MultipartHttpServletRequest request = (MultipartHttpServletRequest) nativeRequest; Class bizClass = bizObj.getClass(); ReflectionUtils.doWithFields(bizClass, field -> { ReflectionUtils.makeAccessible(field); @@ -102,10 +102,21 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { } } + protected boolean isMultipartRequest(NativeWebRequest nativeWebRequest) { + return nativeWebRequest.getNativeRequest() instanceof MultipartHttpServletRequest; + } + + /** + * 获取其它的参数解析器 + * + * @param parameter 业务参数 + * @return 返回合适参数解析器,没有返回null + */ protected HandlerMethodArgumentResolver getOtherArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { - for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { + List argumentResolvers = this.requestMappingHandlerAdapter.getArgumentResolvers(); + for (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) { if (methodArgumentResolver instanceof SopHandlerMethodArgumentResolver) { continue; } @@ -119,4 +130,7 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { return result; } + public void setParamValidator(ParamValidator paramValidator) { + this.paramValidator = paramValidator; + } } \ No newline at end of file diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SopHandlerMethodArgumentResolver.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SopHandlerMethodArgumentResolver.java index 86a8c4fc..535bf70f 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SopHandlerMethodArgumentResolver.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SopHandlerMethodArgumentResolver.java @@ -1,12 +1,11 @@ package com.gitee.sop.servercommon.param; import org.springframework.web.method.support.HandlerMethodArgumentResolver; - -import java.util.List; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; /** * @author tanghc */ public interface SopHandlerMethodArgumentResolver extends HandlerMethodArgumentResolver { - void setResolvers(List resolvers); + void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter); } diff --git a/sop-example/sop-auth/pom.xml b/sop-example/sop-auth/pom.xml index 622a2c0e..0baa41b7 100644 --- a/sop-example/sop-auth/pom.xml +++ b/sop-example/sop-auth/pom.xml @@ -26,7 +26,7 @@ com.gitee.sop sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT org.springframework.cloud diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index 2f0be14b..52fec9d3 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT com.gitee.sop diff --git a/sop-example/sop-easyopen/pom.xml b/sop-example/sop-easyopen/pom.xml index 9b0ddba2..f90b7570 100644 --- a/sop-example/sop-easyopen/pom.xml +++ b/sop-example/sop-easyopen/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT org.springframework.cloud diff --git a/sop-example/sop-springmvc/pom.xml b/sop-example/sop-springmvc/pom.xml index 68dc85fd..5502e361 100644 --- a/sop-example/sop-springmvc/pom.xml +++ b/sop-example/sop-springmvc/pom.xml @@ -20,7 +20,7 @@ com.gitee.sop sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index 02105a16..e11833a5 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-service-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT com.gitee.sop diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java index 835f9db7..5ea2f8ab 100644 --- a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java @@ -105,10 +105,10 @@ public class AlipayController { public StoryVO getStory2(StoryParam story, HttpServletRequest request) { log.info("获取故事信息参数, story: {}", story); // 获取其它参数 - System.out.println(request.getParameter("app_id")); + String app_id = request.getParameter("app_id"); StoryVO storyVO = new StoryVO(); storyVO.id = 1L; - storyVO.name = "白雪公主"; + storyVO.name = "白雪公主, app_id:" + app_id; storyVO.gmt_create = new Date(); return storyVO; } diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TraditionalWebappController.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TraditionalWebappController.java new file mode 100644 index 00000000..d36820c1 --- /dev/null +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TraditionalWebappController.java @@ -0,0 +1,94 @@ +package com.gitee.sop.storyweb.controller; + +import com.gitee.sop.servercommon.annotation.ApiMapping; +import com.gitee.sop.servercommon.util.UploadUtil; +import lombok.Data; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.Collection; + +/** + * 传统web开发实例 + * @author tanghc + */ +@RestController +@RequestMapping("food") +public class TraditionalWebappController { + + + // http://localhost:8081/getFoodById?id=1 网关入口 + // http://localhost:2222/food/getFoodById/?id=12 本地入口 + @ApiMapping(value = "getFoodById", method = RequestMethod.GET) + public Food getFoodById(Integer id) { + Food food = new Food(); + food.setId(id); + food.setName("香蕉"); + food.setPrice(new BigDecimal(20.00)); + return food; + } + + // http://localhost:8081/getFoodById?id=2&version=1.1 网关入口 + // http://localhost:2222/food/getFoodById/?id=12&version=1.1 + @ApiMapping(value = "getFoodById", method = RequestMethod.GET, version = "1.1") + public Food getFoodById2(Integer id) { + Food food = new Food(); + food.setId(id); + food.setName("香蕉2"); + food.setPrice(new BigDecimal(22.00)); + return food; + } + + // http://localhost:8081/getFoodByObj?id=2 + @ApiMapping(value = "getFoodByObj", method = RequestMethod.GET) + public Food getFoodByObj(Food food) { + return food; + } + + // http://localhost:8081/saveFood + @ApiMapping(value = "saveFood", method = RequestMethod.POST) + public Food saveFood(@RequestBody Food food) { + food.setId(3); + return food; + } + + @ApiMapping(value = "foodUpload", method = RequestMethod.POST) + public Food upload(Food food, HttpServletRequest request) { + // 获取上传的文件 + Collection uploadFiles = UploadUtil.getUploadFiles(request); + StringBuilder sb = new StringBuilder(); + for (MultipartFile multipartFile : uploadFiles) { + sb.append(multipartFile.getOriginalFilename()); + } + food.setId(4); + food.setName("文件名称+" + sb.toString()); + return food; + } + + @ApiMapping(value = "foodUpload3", method = RequestMethod.POST) + public Food upload3(Food food, MultipartFile file) { + food.setId(5); + food.setName("文件名称+" + file.getOriginalFilename()); + return food; + } + + @RequestMapping(value = "foodUpload2", method = RequestMethod.POST) + public Food upload2(Food food, MultipartFile file) { + food.setId(4); + food.setName("文件名称2+" + file.getOriginalFilename()); + return food; + } + + @Data + public static class Food { + private Integer id; + private String name; + private BigDecimal price; + } + +} diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index ed98938b..be57783d 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -23,7 +23,7 @@ com.gitee.sop sop-gateway-common - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java index a1d09f27..a2bc0db2 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java @@ -32,4 +32,15 @@ public class RedirectController { request.getRequestDispatcher(path).forward(request, response); } + @RequestMapping("/{method}") + public void redirect2( + @PathVariable("method") String method + , HttpServletRequest request + , HttpServletResponse response + ) throws ServletException, IOException { + request.setAttribute(SopConstants.REDIRECT_METHOD_KEY, method); + request.setAttribute(SopConstants.REDIRECT_VERSION_KEY, "1.0"); + request.getRequestDispatcher(path).forward(request, response); + } + } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenHttp.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenHttp.java index 64dc253d..76250bc0 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenHttp.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenHttp.java @@ -6,6 +6,7 @@ import okhttp3.Cookie; import okhttp3.CookieJar; import okhttp3.FormBody; import okhttp3.HttpUrl; +import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -22,13 +23,21 @@ import java.util.Set; import java.util.concurrent.TimeUnit; /** + * HTTP请求工具 + * * @author tanghc */ public class OpenHttp { + private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); + private Map> cookieStore = new HashMap>(); private OkHttpClient httpClient; + public OpenHttp() { + this(new OpenConfig()); + } + public OpenHttp(OpenConfig openConfig) { this.initHttpClient(openConfig); } @@ -68,25 +77,45 @@ public class OpenHttp { return response.body().string(); } + /** + * 请求json数据,contentType=application/json + * @param url 请求路径 + * @param json json数据 + * @param header header + * @return 返回响应结果 + * @throws IOException + */ + public String requestJson(String url, String json, Map header) throws IOException { + RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json); + Request.Builder requestBuilder = new Request.Builder() + .url(url) + .post(body); + // 添加header + addHeader(requestBuilder, header); + + Request request = requestBuilder.build(); + Response response = httpClient + .newCall(request) + .execute(); + try { + return response.body().string(); + } finally { + response.close(); + } + } + /** * 提交表单 * - * @param url url - * @param form 参数 + * @param url url + * @param form 参数 * @param header header * @param method 请求方式,post,get等 * @return * @throws IOException */ - public String requestFormBody(String url, Map form, Map header, String method) throws IOException { - FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8); - for (Map.Entry entry : form.entrySet()) { - paramBuilder.add(entry.getKey(), entry.getValue()); - } - FormBody formBody = paramBuilder.build(); - Request.Builder requestBuilder = new Request.Builder() - .url(url) - .method(method, formBody); + public String request(String url, Map form, Map header, String method) throws IOException { + Request.Builder requestBuilder = buildRequestBuilder(url, form, method); // 添加header addHeader(requestBuilder, header); @@ -101,6 +130,47 @@ public class OpenHttp { } } + public static Request.Builder buildRequestBuilder(String url, Map form, String method) { + switch (method) { + case "get": + return new Request.Builder() + .url(buildHttpUrl(url, form)) + .get(); + case "head": + return new Request.Builder() + .url(buildHttpUrl(url, form)) + .head(); + case "put": + return new Request.Builder() + .url(url) + .put(buildFormBody(form)); + case "delete": + return new Request.Builder() + .url(url) + .delete(buildFormBody(form)); + default: + return new Request.Builder() + .url(url) + .post(buildFormBody(form)); + } + } + + public static HttpUrl buildHttpUrl(String url, Map form) { + HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); + for (Map.Entry entry : form.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + return urlBuilder.build(); + } + + public static FormBody buildFormBody(Map form) { + FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8); + for (Map.Entry entry : form.entrySet()) { + paramBuilder.add(entry.getKey(), entry.getValue()); + } + return paramBuilder.build(); + } + /** * 提交表单,并且上传文件 * @@ -162,4 +232,5 @@ public class OpenHttp { this.httpClient = httpClient; } + } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java index 3327e2c6..959c3624 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java @@ -42,7 +42,9 @@ public class OpenRequest { } return openHttp.get(url, header); } else { - return openHttp.requestFormBody(url, form, header, requestMethod.name()); + return openHttp.request(url, form, header, requestMethod.name()); + // 下面这种方式也可以,以application/json方式请求 + // return openHttp.requestJson(url, JSON.toJSONString(form), header); } } } catch (IOException e) { diff --git a/sop-website/website-server/pom.xml b/sop-website/website-server/pom.xml index 03056a95..d6ae3866 100644 --- a/sop-website/website-server/pom.xml +++ b/sop-website/website-server/pom.xml @@ -25,7 +25,7 @@ com.gitee.sop sop-registry-api - 1.13.0-SNAPSHOT + 1.13.1-SNAPSHOT diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java index d9e057db..a0ff4e60 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java @@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit; * @author tanghc */ public class HttpTool { - private static final String METHOD_GET = "get"; private Map> cookieStore = new HashMap>(); private OkHttpClient httpClient;