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-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..be7329d6 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/WebappServiceConfiguration.java @@ -0,0 +1,9 @@ +package com.gitee.sop.servercommon.configuration; + +/** + * 通用web + * @author tanghc + */ +public class WebappServiceConfiguration extends BaseServiceConfiguration { + +} 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..351d0096 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; } @@ -163,8 +166,9 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager { * @return 返回文件夹路径 */ protected String uploadFolder(ServiceRouteInfo serviceRouteInfo) throws Exception { + String serviceId = serviceRouteInfo.getServiceId(); // 保存路径 - String savePath = routeRootPath + "/" + serviceRouteInfo.getServiceId(); + String savePath = routeRootPath + "/" + serviceId; String serviceRouteInfoJson = JSON.toJSONString(serviceRouteInfo); log.info("上传service目录到zookeeper,路径:{},内容:{}", savePath, serviceRouteInfoJson); this.zookeeperTool.createOrUpdateData(savePath, serviceRouteInfoJson); @@ -181,11 +185,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 341e4039..c2a7d5f4 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,6 +60,7 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { } } + /** * 获取参数对象,将request中的参数绑定到实体对象中去 * @@ -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,15 +102,27 @@ 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; } if (methodArgumentResolver.supportsParameter(parameter)) { result = methodArgumentResolver; + System.out.println(parameter + " " + result.getClass().getName()); this.argumentResolverCache.put(parameter, result); break; } @@ -119,4 +131,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); }