mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
代码优化
This commit is contained in:
@@ -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<String, String> convertJsonRequestToMap(HttpServletRequest request) {
|
||||
try {
|
||||
String text = getText(request);
|
||||
JSONObject parseObject = JSON.parseObject(text);
|
||||
Map<String, String> params = new HashMap<>(parseObject.size());
|
||||
for (Map.Entry<String, Object> 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;
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
||||
|
@@ -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();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@@ -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<RequestContext> {
|
||||
@Override
|
||||
public Map<String, String> buildRequestParams(RequestContext ctx) {
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
Map<String, String> params = null;
|
||||
|
||||
Map<String, String> 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<RequestContext> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ public class AlipayServiceConfiguration extends BaseServiceConfiguration {
|
||||
protected void doAfter() {
|
||||
super.doAfter();
|
||||
SopHandlerMethodArgumentResolver sopHandlerMethodArgumentResolver = ServiceConfig.getInstance().getMethodArgumentResolver();
|
||||
List<HandlerMethodArgumentResolver> defaultArgumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
|
||||
sopHandlerMethodArgumentResolver.setResolvers(defaultArgumentResolvers);
|
||||
sopHandlerMethodArgumentResolver.setRequestMappingHandlerAdapter(requestMappingHandlerAdapter);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,9 @@
|
||||
package com.gitee.sop.servercommon.configuration;
|
||||
|
||||
/**
|
||||
* 通用web
|
||||
* @author tanghc
|
||||
*/
|
||||
public class WebappServiceConfiguration extends BaseServiceConfiguration {
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
@@ -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<GatewayRouteDefinition> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
|
||||
new ConcurrentHashMap<>(256);
|
||||
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap<>(256);
|
||||
|
||||
private final ParamValidator paramValidator = new ServiceParamValidator();
|
||||
private ParamValidator paramValidator = new ServiceParamValidator();
|
||||
|
||||
private List<HandlerMethodArgumentResolver> argumentResolvers = Collections.emptyList();
|
||||
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
|
||||
|
||||
@Override
|
||||
public void setResolvers(List<HandlerMethodArgumentResolver> 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<HandlerMethodArgumentResolver> 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;
|
||||
}
|
||||
}
|
@@ -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<HandlerMethodArgumentResolver> resolvers);
|
||||
void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter);
|
||||
}
|
||||
|
Reference in New Issue
Block a user