diff --git a/src/org/redkale/net/http/Rest.java b/src/org/redkale/net/http/Rest.java index 09b28eee9..62387d378 100644 --- a/src/org/redkale/net/http/Rest.java +++ b/src/org/redkale/net/http/Rest.java @@ -60,6 +60,42 @@ public final class Rest { private Rest() { } + public static class MethodParamClassVisitor extends ClassVisitor { + + private final Map> fieldmap; + + public MethodParamClassVisitor(int api, final Map> fieldmap) { + super(api); + this.fieldmap = fieldmap; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (java.lang.reflect.Modifier.isStatic(access)) return null; + List fieldnames = new ArrayList<>(); + fieldmap.put(name + ":" + desc, fieldnames); + return new MethodVisitor(Opcodes.ASM5) { + @Override + public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { + if (index > 0) fieldnames.add(name); + } + }; + } + + //返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多 + public static Map> getMethodParamNames(Class clazz) { + String n = clazz.getName(); + InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); + Map> map = new HashMap<>(); + if (in == null) return map; + try { + new ClassReader(Utility.readBytesThenClose(in)).accept(new MethodParamClassVisitor(Opcodes.ASM5, map), 0); + } catch (Exception e) { //无需理会 + } + return map; + } + } + static String getWebModuleName(Class serviceType) { final RestService controller = serviceType.getAnnotation(RestService.class); if (controller == null) return serviceType.getSimpleName().replaceAll("Service.*$", "").toLowerCase(); @@ -217,6 +253,7 @@ public final class Rest { if (entrys.isEmpty()) return null; //没有可WebMapping的方法 //将每个Service可转换的方法生成HttpServlet对应的WebMapping方法 + final Map> asmParamMap = MethodParamClassVisitor.getMethodParamNames(serviceType); for (final MappingEntry entry : entrys) { final Method method = entry.mappingMethod; final Class returnType = method.getReturnType(); @@ -263,11 +300,12 @@ public final class Rest { final int maxStack = 3 + params.length; List varInsns = new ArrayList<>(); int maxLocals = 4; - int argIndex = 0; + List asmParamNames = asmParamMap == null ? null : asmParamMap.get(method.getName() + ":" + Type.getMethodDescriptor(method)); List paramlist = new ArrayList<>(); //解析方法中的每个参数 - for (final Parameter param : params) { + for (int i = 0; i < params.length; i++) { + final Parameter param = params[i]; final Class ptype = param.getType(); String n = null; String comment = ""; @@ -310,13 +348,14 @@ public final class Rest { if (annpara != null) required = annpara.required(); if (n == null) n = (annpara == null || annpara.name().isEmpty()) ? null : annpara.name(); if (n == null && ptype == userType) n = "&"; //用户类型特殊处理 + if (n == null && asmParamNames != null && asmParamNames.size() > i) n = asmParamNames.get(i); if (n == null) { if (param.isNamePresent()) { n = param.getName(); } else if (ptype == Flipper.class) { n = "flipper"; } else { - n = (++argIndex > 1) ? ("bean" + argIndex) : "bean"; + n = ("bean" + i); } } if (annhead == null && anncookie == null && annaddr == null diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index e6745a956..8a43768cc 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -104,6 +104,7 @@ public interface Creator { if (constructorDesc != null && !constructorDesc.equals(desc)) return null; if (this.started) return null; this.started = true; + //返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多 return new MethodVisitor(Opcodes.ASM5) { @Override public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { @@ -113,7 +114,7 @@ public interface Creator { } } - public static SimpleEntry[] getConstructorField(Class clazz, String constructorDesc) { + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String constructorDesc) { String n = clazz.getName(); InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); if (in == null) return null; @@ -131,10 +132,18 @@ public interface Creator { final List fieldnames = new ArrayList<>(); new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0); if (fieldnames.isEmpty()) return null; - return getConstructorField(clazz, fieldnames.toArray(new String[fieldnames.size()])); + if (paramcount == fieldnames.size()) { + return getConstructorField(clazz, paramcount, fieldnames.toArray(new String[fieldnames.size()])); + } else { + String[] fs = new String[paramcount]; + for (int i = 0; i < fs.length; i++) { + fs[i] = fieldnames.get(i); + } + return getConstructorField(clazz, paramcount, fs); + } } - public static SimpleEntry[] getConstructorField(Class clazz, String[] names) { + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String[] names) { SimpleEntry[] se = new SimpleEntry[names.length]; for (int i = 0; i < names.length; i++) { //查询参数名对应的Field try { @@ -147,7 +156,7 @@ public interface Creator { return se; } - public static SimpleEntry[] getConstructorField(Class clazz, Parameter[] params) { + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, Parameter[] params) { SimpleEntry[] se = new SimpleEntry[params.length]; for (int i = 0; i < params.length; i++) { //查询参数名对应的Field try { @@ -232,7 +241,7 @@ public interface Creator { for (Constructor c : clazz.getConstructors()) { ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); if (cp == null) continue; - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value()); + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -250,7 +259,7 @@ public interface Creator { //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -263,7 +272,7 @@ public interface Creator { if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue; ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); if (cp == null) continue; - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value()); + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -282,7 +291,7 @@ public interface Creator { //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields;