mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
4.4.2
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# changelog
|
||||
|
||||
## 4.4.2
|
||||
|
||||
- 优化参数绑定
|
||||
|
||||
## 4.4.1
|
||||
|
||||
- 修复单值参数绑定问题
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>doc</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<!-- Generic properties -->
|
||||
|
2
pom.xml
2
pom.xml
@@ -11,7 +11,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<description>一个开放平台解决方案项目,基于Spring Cloud实现,目标是能够让用户快速得搭建起自己的开放平台</description>
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -5,13 +5,13 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>sop-admin-server</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sdk-java</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- http请求 -->
|
||||
<dependency>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
@@ -38,7 +38,6 @@
|
||||
<springfox-spring-web.version>2.9.2</springfox-spring-web.version>
|
||||
<springfox-swagger2.version>2.9.2</springfox-swagger2.version>
|
||||
<easyopen.version>1.16.9</easyopen.version>
|
||||
<asm.version>6.2</asm.version>
|
||||
<pagehelper.version>5.2.0</pagehelper.version>
|
||||
</properties>
|
||||
|
||||
@@ -74,11 +73,6 @@
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- optional -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
@@ -257,12 +251,6 @@
|
||||
<version>${commons-logging.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>${asm.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
|
@@ -2,19 +2,17 @@ package com.gitee.sop.servercommon.param;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import com.gitee.sop.servercommon.annotation.Open;
|
||||
import com.gitee.sop.servercommon.bean.OpenContext;
|
||||
import com.gitee.sop.servercommon.bean.OpenContextImpl;
|
||||
import com.gitee.sop.servercommon.bean.ParamNames;
|
||||
import com.gitee.sop.servercommon.bean.ServiceContext;
|
||||
import com.gitee.sop.servercommon.util.FieldUtil;
|
||||
import com.gitee.sop.servercommon.util.OpenUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
@@ -36,7 +34,6 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.security.Principal;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
@@ -113,7 +110,6 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
|
||||
if (special) {
|
||||
NEED_INIT_OPEN_CONTEXT.add(methodParameter);
|
||||
}
|
||||
this.wrapSingleParam(methodParameter, open);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,20 +118,6 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
|
||||
return NEED_INIT_OPEN_CONTEXT.contains(methodParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 包装单个值参数
|
||||
* @param methodParameter 参数信息
|
||||
* @param open open注解
|
||||
*/
|
||||
private void wrapSingleParam(MethodParameter methodParameter, Open open) {
|
||||
Parameter parameter = methodParameter.getParameter();
|
||||
boolean isNumberStringEnumType = FieldUtil.isNumberStringEnumType(parameter.getType());
|
||||
if (isNumberStringEnumType) {
|
||||
log.debug("包装参数,方法:{},参数名:{}", methodParameter.getMethod(), parameter.getName());
|
||||
SingleParameterContext.add(parameter, open);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(
|
||||
MethodParameter methodParameter
|
||||
@@ -164,29 +146,17 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
|
||||
Object paramObj = this.getParamObject(methodParameter, nativeWebRequest);
|
||||
if (paramObj != null) {
|
||||
// JSR-303验证
|
||||
if (paramObj instanceof SingleParameterWrapper) {
|
||||
SingleParameterWrapper parameterWrapper = (SingleParameterWrapper) paramObj;
|
||||
paramValidator.validateBizParam(parameterWrapper.getWrapperObject());
|
||||
return parameterWrapper.getParamValue();
|
||||
} else {
|
||||
paramValidator.validateBizParam(paramObj);
|
||||
return paramObj;
|
||||
}
|
||||
}
|
||||
HandlerMethodArgumentResolver resolver = getOtherArgumentResolver(methodParameter);
|
||||
if (resolver != null) {
|
||||
Object param = resolver.resolveArgument(
|
||||
return resolver.resolveArgument(
|
||||
methodParameter
|
||||
, modelAndViewContainer
|
||||
, nativeWebRequest
|
||||
, webDataBinderFactory
|
||||
);
|
||||
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
|
||||
if (openContext instanceof OpenContextImpl) {
|
||||
OpenContextImpl openContextImpl = (OpenContextImpl) openContext;
|
||||
openContextImpl.setBizObject(param);
|
||||
}
|
||||
return param;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -217,22 +187,11 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
|
||||
Map<String, Object> requestParams = openContext.getParameterMap();
|
||||
Object bizObj = requestParams.get(ParamNames.BIZ_CONTENT_NAME);
|
||||
String bizContent = bizObj == null ? null : bizObj.toString();
|
||||
if (bizContent == null) {
|
||||
if (StringUtils.isEmpty(bizContent)) {
|
||||
return null;
|
||||
}
|
||||
// 方法参数类型
|
||||
Class<?> parameterType = methodParameter.getParameterType();
|
||||
SingleParameterContextValue singleValue = SingleParameterContext.get(openContext.getMethod(), openContext.getVersion());
|
||||
// 如果是单值参数
|
||||
if (singleValue != null) {
|
||||
JSONObject jsonObj = JSON.parseObject(bizContent);
|
||||
Object paramValue = jsonObj.getObject(singleValue.getParameterName(), parameterType);
|
||||
Object wrapperObject = jsonObj.toJavaObject(singleValue.getWrapClass());
|
||||
SingleParameterWrapper singleParameterWrapper = new SingleParameterWrapper();
|
||||
singleParameterWrapper.setParamValue(paramValue);
|
||||
singleParameterWrapper.setWrapperObject(wrapperObject);
|
||||
return singleParameterWrapper;
|
||||
}
|
||||
Object param;
|
||||
try {
|
||||
param = JSON.parseObject(bizContent, parameterType);
|
||||
|
@@ -1,186 +0,0 @@
|
||||
package com.gitee.sop.servercommon.param;
|
||||
|
||||
|
||||
import com.gitee.sop.servercommon.util.FieldUtil;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 包装单个参数
|
||||
* <code>
|
||||
* public class WrapperParam0id implements SingleValue {
|
||||
* public String id;
|
||||
*
|
||||
* public Object fetchValue() {
|
||||
* return this.id;
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
public class SingleParameterClassCreator implements Opcodes {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SingleParameterClassCreator.class);
|
||||
|
||||
private static final String FOLDER_END_CHAR = "/";
|
||||
|
||||
private static final String CLASS_FILE_SUFFIX = ".class";
|
||||
|
||||
private static final String WRAPPER_PARAM = "WrapperParam";
|
||||
|
||||
private static final String PKG = "com/gitee/sop/servercommon/gen/";
|
||||
private static final String OBJECT = "java/lang/Object";
|
||||
|
||||
private static final ParameterClassLoader CLASS_LOADER = new ParameterClassLoader();
|
||||
|
||||
private static final AtomicInteger i = new AtomicInteger();
|
||||
|
||||
// 生成class文件的保存路径
|
||||
private String savePath;
|
||||
|
||||
/**
|
||||
* 生成一个类,里面指放这个字段
|
||||
*
|
||||
* @param parameter 字段,只能是基本类型或字符串类型
|
||||
* @return 如果不是基本类型或字符串类型,返回null
|
||||
*/
|
||||
public Class<?> create(Parameter parameter, String paramName) {
|
||||
Class<?> paramType = parameter.getType();
|
||||
if (!FieldUtil.isNumberStringEnumType(paramType)) {
|
||||
return null;
|
||||
}
|
||||
/* *******************************class********************************************** */
|
||||
// 创建一个ClassWriter, 以生成一个新的类
|
||||
ClassWriter classWriter = new ClassWriter(0);
|
||||
// 类名
|
||||
String className = WRAPPER_PARAM + i.incrementAndGet() + paramName;
|
||||
// 类路径名:com/gitee/sop/service/gen/WrapperParam
|
||||
String classpathName = PKG + className;
|
||||
classWriter.visit(V1_8, ACC_PUBLIC, classpathName, null, OBJECT, null);
|
||||
|
||||
/* ********************************constructor********************************************* */
|
||||
MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
|
||||
null);
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
methodVisitor.visitMethodInsn(INVOKESPECIAL, OBJECT, "<init>", "()V", false);
|
||||
methodVisitor.visitInsn(RETURN);
|
||||
methodVisitor.visitMaxs(1, 1);
|
||||
methodVisitor.visitEnd();
|
||||
|
||||
|
||||
/* ************************************parameter***************************************** */
|
||||
// 生成String name字段, Ljava/lang/String;
|
||||
Type type = Type.getType(paramType);
|
||||
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC, paramName, type.getDescriptor(), null, null);
|
||||
// 生成验证注解
|
||||
Annotation[] annotations = parameter.getAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
ValidationAnnotationDefinition validationAnnotationDefinition = ValidationAnnotationDefinitionFactory.build(annotation);
|
||||
if (validationAnnotationDefinition == null) {
|
||||
continue;
|
||||
}
|
||||
Class<?> annoClass = validationAnnotationDefinition.getAnnotationClass();
|
||||
Type annoType = Type.getType(annoClass);
|
||||
AnnotationVisitor annotationVisitor = fieldVisitor.visitAnnotation(annoType.getDescriptor(), true);
|
||||
Map<String, Object> properties = validationAnnotationDefinition.getProperties();
|
||||
if (properties != null) {
|
||||
try {
|
||||
Set<Map.Entry<String, Object>> entrySet = properties.entrySet();
|
||||
for (Map.Entry<String, Object> entry : entrySet) {
|
||||
Object val = entry.getValue();
|
||||
if (val != null) {
|
||||
// 设置枚举值
|
||||
if (val.getClass().isEnum()) {
|
||||
Type eType = Type.getType(val.getClass());
|
||||
annotationVisitor.visitEnum(entry.getKey(), eType.getDescriptor(), val.toString());
|
||||
} else if (val instanceof Class<?>) {
|
||||
// val是Class类型
|
||||
Type vType = Type.getType((Class<?>) val);
|
||||
annotationVisitor.visit(entry.getKey(), vType);
|
||||
} else {
|
||||
annotationVisitor.visit(entry.getKey(), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("ASM生成注解出错", e);
|
||||
}
|
||||
}
|
||||
// 结束生成注解
|
||||
annotationVisitor.visitEnd();
|
||||
logger.debug("ASM生成参数注解,参数:{},注解:{},注解属性:{}", paramName, annoClass.getName(), properties);
|
||||
}
|
||||
fieldVisitor.visitEnd();
|
||||
|
||||
classWriter.visitEnd();
|
||||
|
||||
/* **********************************generate and load******************************************* */
|
||||
byte[] code = classWriter.toByteArray();
|
||||
|
||||
if (StringUtils.isNotBlank(savePath)) {
|
||||
if (!savePath.endsWith(FOLDER_END_CHAR)) {
|
||||
savePath = savePath + FOLDER_END_CHAR;
|
||||
}
|
||||
this.writeClassFile(code, savePath + className + CLASS_FILE_SUFFIX);
|
||||
}
|
||||
|
||||
Class<?> clazz = CLASS_LOADER.defineClass(code);
|
||||
logger.debug("生成参数包装类:{},包装参数名:{},参数类型:{}", clazz.getName(), paramName, paramType);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
protected void writeClassFile(byte[] code, String filepath) {
|
||||
// 将二进制流写到本地磁盘上
|
||||
try {
|
||||
FileUtils.writeByteArrayToFile(new File(filepath), code);
|
||||
} catch (IOException e) {
|
||||
logger.error("写文件错误,filepath:" + filepath, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSavePath(String savePath) {
|
||||
this.savePath = savePath;
|
||||
}
|
||||
|
||||
|
||||
// 自定义类加载器
|
||||
static class ParameterClassLoader extends ClassLoader {
|
||||
public ParameterClassLoader() {
|
||||
/*
|
||||
指定父加载器,不指定默认为AppClassLoader
|
||||
springboot启动会使用自带的org.springframework.boot.loader.LaunchedURLClassLoader
|
||||
如果不指定,会出现加载器不一致,导致ASM生成的class获取不到字段的注解。
|
||||
因此ASM生成的class必须使用当前ClassLoader进行生成。
|
||||
*/
|
||||
super(Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载class
|
||||
*
|
||||
* @param clazz 字节码
|
||||
* @return
|
||||
*/
|
||||
public Class<?> defineClass(byte[] clazz) {
|
||||
return this.defineClass(null, clazz, 0, clazz.length);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package com.gitee.sop.servercommon.param;
|
||||
|
||||
import com.gitee.sop.servercommon.annotation.Open;
|
||||
import com.gitee.sop.servercommon.bean.ServiceConfig;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 存放单个参数
|
||||
* @author tanghc
|
||||
*/
|
||||
public class SingleParameterContext {
|
||||
|
||||
private static SingleParameterClassCreator singleFieldWrapper = new SingleParameterClassCreator();
|
||||
|
||||
private static final Map<String, SingleParameterContextValue> context = new ConcurrentHashMap<>(16);
|
||||
|
||||
/**
|
||||
* 添加单个参数
|
||||
* @param parameter 接口单个参数
|
||||
* @param open open注解
|
||||
*/
|
||||
public static void add(Parameter parameter, Open open) {
|
||||
String version = open.version();
|
||||
version = "".equals(version) ? ServiceConfig.getInstance().getDefaultVersion() : version;
|
||||
String parameterName = parameter.getName();
|
||||
String key = open.value() + version + parameterName;
|
||||
Class<?> wrapClass = singleFieldWrapper.create(parameter, parameterName);
|
||||
SingleParameterContextValue value = new SingleParameterContextValue();
|
||||
value.setParameterName(parameterName);
|
||||
value.setWrapClass(wrapClass);
|
||||
context.put(key, value);
|
||||
}
|
||||
|
||||
public static SingleParameterContextValue get(String name, String version) {
|
||||
return context.get(name + version);
|
||||
}
|
||||
|
||||
public static void setSingleFieldWrapper(SingleParameterClassCreator singleFieldWrapper) {
|
||||
SingleParameterContext.singleFieldWrapper = singleFieldWrapper;
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package com.gitee.sop.servercommon.param;
|
||||
|
||||
public class SingleParameterContextValue {
|
||||
/** 参数名称 */
|
||||
private String parameterName;
|
||||
private Class<?> wrapClass;
|
||||
|
||||
public String getParameterName() {
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public void setParameterName(String parameterName) {
|
||||
this.parameterName = parameterName;
|
||||
}
|
||||
|
||||
public Class<?> getWrapClass() {
|
||||
return wrapClass;
|
||||
}
|
||||
|
||||
public void setWrapClass(Class<?> wrapClass) {
|
||||
this.wrapClass = wrapClass;
|
||||
}
|
||||
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package com.gitee.sop.servercommon.param;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class SingleParameterWrapper {
|
||||
/** 包裹类实例 */
|
||||
private Object wrapperObject;
|
||||
/** 参数值 */
|
||||
private Object paramValue;
|
||||
|
||||
public Object getWrapperObject() {
|
||||
return wrapperObject;
|
||||
}
|
||||
|
||||
public void setWrapperObject(Object wrapperObject) {
|
||||
this.wrapperObject = wrapperObject;
|
||||
}
|
||||
|
||||
public Object getParamValue() {
|
||||
return paramValue;
|
||||
}
|
||||
|
||||
public void setParamValue(Object paramValue) {
|
||||
this.paramValue = paramValue;
|
||||
}
|
||||
}
|
@@ -1,128 +0,0 @@
|
||||
package com.gitee.sop.servercommon.util;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class FieldUtil {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FieldUtil.class);
|
||||
|
||||
private static final String CLASS_SUFFIX = ".class";
|
||||
|
||||
private FieldUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断这个字段是否是数字类型或字符串类型或枚举类型
|
||||
*
|
||||
* @param type 字段类型
|
||||
* @return true:是数字或字符串类型或枚举类型
|
||||
*/
|
||||
public static boolean isNumberStringEnumType(Class<?> type) {
|
||||
if (type == String.class) {
|
||||
return true;
|
||||
}
|
||||
if (type.getGenericSuperclass() == Number.class) {
|
||||
return true;
|
||||
}
|
||||
if (type.isPrimitive()) {
|
||||
return true;
|
||||
}
|
||||
if (type.isEnum()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定类指定方法的参数名
|
||||
* @param clazz 要获取参数名的方法所属的类
|
||||
* @param method 要获取参数名的方法
|
||||
* @param index 参数索引,从0开始
|
||||
* @return 返回指定类指定方法的参数名,没有返回空字符串
|
||||
*/
|
||||
public static String getMethodParameterName(Class<?> clazz, final Method method, int index) {
|
||||
String[] names = getMethodParameterNamesByAsm(clazz, method);
|
||||
if (names.length == 0) {
|
||||
return "";
|
||||
}
|
||||
return names[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定类指定方法的参数名
|
||||
*
|
||||
* @param clazz 要获取参数名的方法所属的类
|
||||
* @param method 要获取参数名的方法
|
||||
* @return 按参数顺序排列的参数名列表,如果没有参数,则返回空数组
|
||||
*/
|
||||
public static String[] getMethodParameterNamesByAsm(Class<?> clazz, final Method method) {
|
||||
final Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes == null || parameterTypes.length == 0) {
|
||||
return new String[0];
|
||||
}
|
||||
final Type[] types = new Type[parameterTypes.length];
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
types[i] = Type.getType(parameterTypes[i]);
|
||||
}
|
||||
final String[] parameterNames = new String[parameterTypes.length];
|
||||
// 解决clazz对象是cglib对象导致空指针异常
|
||||
// 获取真实的class,如果是cglib类,则返回父类class
|
||||
Class<?> realClass = ClassUtils.getUserClass(clazz);
|
||||
String className = realClass.getName();
|
||||
int lastDotIndex = className.lastIndexOf('.');
|
||||
className = className.substring(lastDotIndex + 1) + CLASS_SUFFIX;
|
||||
InputStream is = realClass.getResourceAsStream(className);
|
||||
try {
|
||||
ClassReader classReader = new ClassReader(is);
|
||||
classReader.accept(new ClassVisitor(Opcodes.ASM6) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
// 只处理指定的方法
|
||||
Type[] argumentTypes = Type.getArgumentTypes(desc);
|
||||
if (!method.getName().equals(name) || !Arrays.equals(argumentTypes, types)) {
|
||||
return null;
|
||||
}
|
||||
return new MethodVisitor(Opcodes.ASM6) {
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
|
||||
int i = index - 1;
|
||||
// 如果是静态方法,则第一就是参数
|
||||
// 如果不是静态方法,则第一个是"this",然后才是方法的参数
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
i = index;
|
||||
}
|
||||
if (i >= 0 && i < parameterNames.length) {
|
||||
parameterNames[i] = name;
|
||||
}
|
||||
super.visitLocalVariable(name, desc, signature, start,
|
||||
end, index);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}, 0);
|
||||
} catch (IOException e) {
|
||||
log.error("生成asm失败,oriClass:{}, realClass:{} method:{}", clazz.getName(), realClass.getName(), method.toGenericString(), e);
|
||||
}
|
||||
return parameterNames;
|
||||
}
|
||||
|
||||
}
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -151,9 +151,7 @@ public class Example1001_BaseController {
|
||||
// 参数绑定
|
||||
@Open(value = "story.oneparam", version = "1.1")
|
||||
@GetMapping("/oneParam/v2")
|
||||
public StoryResult oneParamV2(
|
||||
@NotNull(message = "id不能为空")
|
||||
@Min(value = 1, message = "id必须大于0") Integer id) {
|
||||
public StoryResult oneParamV2(Integer id) {
|
||||
StoryResult result = new StoryResult();
|
||||
result.setName("id:" + id);
|
||||
return result;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -4,13 +4,13 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>sdk-java</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<!-- Generic properties -->
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -19,6 +19,7 @@ public class OneParamTest extends TestBase {
|
||||
// 平台提供的私钥
|
||||
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
|
||||
|
||||
// 演示没有biz_content,用于绑定单个参数
|
||||
@Test
|
||||
public void testGet() throws Exception {
|
||||
|
||||
@@ -33,11 +34,9 @@ public class OneParamTest extends TestBase {
|
||||
params.put("version", "1.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, Object> bizContent = new HashMap<>();
|
||||
bizContent.put("id", "aaa");
|
||||
bizContent.put("name", "jim");
|
||||
params.put("id", "aaa");
|
||||
params.put("name", "jim");
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
params.put("sign", sign);
|
||||
@@ -68,10 +67,8 @@ public class OneParamTest extends TestBase {
|
||||
params.put("version", "1.1");
|
||||
|
||||
// 业务参数
|
||||
Map<String, Object> bizContent = new HashMap<>();
|
||||
bizContent.put("id", "1");
|
||||
params.put("id", "1");
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
params.put("sign", sign);
|
||||
@@ -102,10 +99,8 @@ public class OneParamTest extends TestBase {
|
||||
params.put("version", "1.2");
|
||||
|
||||
// 业务参数
|
||||
Map<String, Object> bizContent = new HashMap<>();
|
||||
bizContent.put("typeEnum", "MOBILE");
|
||||
params.put("typeEnum", "MOBILE");
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
params.put("sign", sign);
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-website</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
Reference in New Issue
Block a user