This commit is contained in:
@@ -56,6 +56,7 @@ public final class Rest {
|
||||
final String webServletDesc = Type.getDescriptor(WebServlet.class);
|
||||
final String httpRequestDesc = Type.getDescriptor(HttpRequest.class);
|
||||
final String httpResponseDesc = Type.getDescriptor(HttpResponse.class);
|
||||
final String attrDesc = Type.getDescriptor(org.redkale.util.Attribute.class);
|
||||
final String authDesc = Type.getDescriptor(HttpBaseServlet.AuthIgnore.class);
|
||||
final String actionDesc = Type.getDescriptor(HttpBaseServlet.WebAction.class);
|
||||
final String serviceTypeString = serviceType.getName().replace('.', '/');
|
||||
@@ -135,6 +136,7 @@ public final class Rest {
|
||||
}
|
||||
|
||||
final List<MappingEntry> entrys = new ArrayList<>();
|
||||
final Map<String, org.redkale.util.Attribute> restAttributes = new LinkedHashMap<>();
|
||||
|
||||
for (final Method method : serviceType.getMethods()) {
|
||||
Class[] extypes = method.getExceptionTypes();
|
||||
@@ -407,6 +409,68 @@ public final class Rest {
|
||||
mv.visitTypeInsn(CHECKCAST, ptype.getName().replace('.', '/'));
|
||||
mv.visitVarInsn(ASTORE, maxLocals);
|
||||
varInsns.add(new int[]{ALOAD, maxLocals});
|
||||
|
||||
//构建 RestHeader、RestCookie、RestAddress 等赋值操作
|
||||
Class loop = ptype;
|
||||
Set<String> fields = new HashSet<>();
|
||||
Map<String, String> attrParaNames = new LinkedHashMap<>();
|
||||
do {
|
||||
for (Field field : loop.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
if (Modifier.isFinal(field.getModifiers())) continue;
|
||||
if (fields.contains(field.getName())) continue;
|
||||
RestHeader rh = field.getAnnotation(RestHeader.class);
|
||||
RestCookie rc = field.getAnnotation(RestCookie.class);
|
||||
RestAddress ra = field.getAnnotation(RestAddress.class);
|
||||
if (rh == null && rc == null && ra == null) continue;
|
||||
if (rh != null && field.getType() != String.class) throw new RuntimeException("@RestHeader must on String Field in " + field);
|
||||
if (rc != null && field.getType() != String.class) throw new RuntimeException("@RestCookie must on String Field in " + field);
|
||||
if (ra != null && field.getType() != String.class) throw new RuntimeException("@RestAddress must on String Field in " + field);
|
||||
org.redkale.util.Attribute attr = org.redkale.util.Attribute.create(loop, field);
|
||||
String attrFieldName;
|
||||
String restname = "";
|
||||
if (rh != null) {
|
||||
attrFieldName = "_redkale_attr_header_" + restAttributes.size();
|
||||
restname = rh.value();
|
||||
} else if (rc != null) {
|
||||
attrFieldName = "_redkale_attr_cookie_" + restAttributes.size();
|
||||
restname = rc.value();
|
||||
} else if (ra != null) {
|
||||
attrFieldName = "_redkale_attr_address_" + restAttributes.size();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
restAttributes.put(attrFieldName, attr);
|
||||
attrParaNames.put(attrFieldName, restname);
|
||||
fields.add(field.getName());
|
||||
}
|
||||
} while ((loop = loop.getSuperclass()) != Object.class);
|
||||
|
||||
if (!attrParaNames.isEmpty()) { //参数存在 RestHeader、RestCookie、RestAddress字段
|
||||
mv.visitVarInsn(ALOAD, maxLocals);
|
||||
Label lif = new Label();
|
||||
mv.visitJumpInsn(IFNULL, lif); //if(bean != null) {
|
||||
for (Map.Entry<String, String> en : attrParaNames.entrySet()) {
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitFieldInsn(GETFIELD, newDynName, en.getKey(), attrDesc);
|
||||
mv.visitVarInsn(ALOAD, maxLocals);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
if (en.getKey().contains("_header_")) {
|
||||
mv.visitLdcInsn(en.getValue());
|
||||
mv.visitLdcInsn("");
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getHeader", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
|
||||
} else if (en.getKey().contains("_cookie_")) {
|
||||
mv.visitLdcInsn(en.getValue());
|
||||
mv.visitLdcInsn("");
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getCookie", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
|
||||
} else if (en.getKey().contains("_address_")) {
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRemoteAddr", "()Ljava/lang/String;", false);
|
||||
}
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, "org/redkale/util/Attribute", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", true);
|
||||
}
|
||||
mv.visitLabel(lif); // end if }
|
||||
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{ptype.getName().replace('.', '/')}, 0, null);
|
||||
}
|
||||
}
|
||||
maxLocals++;
|
||||
paramMaps.add(paramMap);
|
||||
@@ -671,7 +735,13 @@ public final class Rest {
|
||||
mv.visitMaxs(maxStack, maxLocals);
|
||||
actionMap.put("params", paramMaps);
|
||||
actionMaps.add(actionMap);
|
||||
} // end for each
|
||||
} // end for each
|
||||
|
||||
for (String attrname : restAttributes.keySet()) {
|
||||
fv = cw.visitField(ACC_PRIVATE, attrname, attrDesc, null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
||||
classMap.put("actions", actionMaps);
|
||||
|
||||
{ //toString函数
|
||||
@@ -691,7 +761,13 @@ public final class Rest {
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
return ((Class<T>) newClazz).newInstance();
|
||||
T obj = ((Class<T>) newClazz).newInstance();
|
||||
for (Map.Entry<String, org.redkale.util.Attribute> en : restAttributes.entrySet()) {
|
||||
Field attrField = newClazz.getDeclaredField(en.getKey());
|
||||
attrField.setAccessible(true);
|
||||
attrField.set(obj, en.getValue());
|
||||
}
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* 只能注解于Service类的方法的参数或参数内的字段
|
||||
* 只能注解于Service类的方法的参数或参数内的String字段
|
||||
* <p>
|
||||
* 详情见: http://redkale.org
|
||||
*
|
||||
|
||||
@@ -17,16 +17,16 @@ import org.redkale.util.Attribute;
|
||||
*/
|
||||
public abstract class RestHttpServlet<T> extends HttpBaseServlet {
|
||||
|
||||
Attribute[] _paramAttrs; // 为null表示无DynCall处理,index=0固定为null, 其他为参数标记的DynCall回调方法
|
||||
|
||||
protected abstract T currentUser(HttpRequest req) throws IOException;
|
||||
|
||||
Attribute[] _paramAttrs; // 为null表示无DynCall处理,index=0固定为null, 其他为参数标记的DynCall回调方法
|
||||
|
||||
protected void _callParameter(final HttpResponse response, final Object... params) {
|
||||
if (_paramAttrs == null) return;
|
||||
for (int i = 1; i < _paramAttrs.length; i++) {
|
||||
org.redkale.util.Attribute attr = _paramAttrs[i];
|
||||
if (attr == null) continue;
|
||||
|
||||
|
||||
//convert.convertTo(out, attr.type(), attr.get(params[i - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,25 @@ public class AsmMethodVisitor {
|
||||
if (debug) System.out.println("mv.visitVarInsn(" + opcodes[opcode] + ", " + var + ");");
|
||||
}
|
||||
|
||||
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
|
||||
visitor.visitFrame(type, nLocal, local, nStack, stack);
|
||||
if (debug) {
|
||||
String typestr = "" + type;
|
||||
if (type == -1) {
|
||||
typestr = "Opcodes.F_NEW";
|
||||
} else if (type == 1) {
|
||||
typestr = "Opcodes.F_APPEND";
|
||||
} else if (type == 2) {
|
||||
typestr = "Opcodes.F_CHOP";
|
||||
} else if (type == 3) {
|
||||
typestr = "Opcodes.F_SAME";
|
||||
} else if (type == 4) {
|
||||
typestr = "Opcodes.F_SAME1";
|
||||
}
|
||||
System.out.println("mv.visitFrame(" + typestr + ", " + nLocal + ", " + Arrays.toString(local) + ", " + nStack + ", " + Arrays.toString(stack) + ");");
|
||||
}
|
||||
}
|
||||
|
||||
public void visitJumpInsn(int opcode, Label var) { //调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建
|
||||
visitor.visitJumpInsn(opcode, var);
|
||||
if (debug) {
|
||||
|
||||
@@ -44,17 +44,17 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
* public String get(Record obj) {
|
||||
* return obj.getName();
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @Override
|
||||
* public void set(Record obj, String value) {
|
||||
* obj.setName(value);
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @Override
|
||||
* public Class type() {
|
||||
* return String.class;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @Override
|
||||
* public Class declaringClass() {
|
||||
* return Record.class;
|
||||
@@ -421,6 +421,8 @@ public interface Attribute<T, F> {
|
||||
column = tgetter.getReturnType();
|
||||
} else if (tsetter != null) {
|
||||
column = tsetter.getParameterTypes()[0];
|
||||
} else if (fieldtype == null) {
|
||||
throw new RuntimeException("[" + clazz + "]have no public field or setter or getter");
|
||||
}
|
||||
final Class pcolumn = column;
|
||||
if (column.isPrimitive()) column = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(column, 1), 0).getClass();
|
||||
|
||||
Reference in New Issue
Block a user