This commit is contained in:
@@ -12,7 +12,7 @@ import java.io.IOException;
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
@@ -51,6 +51,45 @@ public abstract class HttpBaseServlet extends HttpServlet {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 配合 @WebParam 使用。
|
||||
* 用于对@WebParam中参数的来源类型
|
||||
*
|
||||
* <p>
|
||||
* 详情见: http://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
protected enum ParamSourceType {
|
||||
|
||||
PARAMETER, HEADER, COOKIE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配合 @WebAction 使用。
|
||||
* 用于对@WebAction方法中参数描述
|
||||
*
|
||||
* <p>
|
||||
* 详情见: http://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@Target({ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
protected @interface WebParam {
|
||||
|
||||
String value(); //参数名
|
||||
|
||||
Class type(); //参数的数据类型
|
||||
|
||||
String comment() default ""; //备注描述
|
||||
|
||||
ParamSourceType src() default ParamSourceType.PARAMETER; //参数来源类型
|
||||
|
||||
int radix() default 10; //转换数字byte/short/int/long时所用的进制数, 默认10进制
|
||||
}
|
||||
|
||||
/**
|
||||
* 配合 HttpBaseServlet 使用。
|
||||
* 用于对@WebServlet对应的url进行细分。 其url必须是包含WebServlet中定义的前缀, 且不能是正则表达式
|
||||
@@ -72,6 +111,8 @@ public abstract class HttpBaseServlet extends HttpServlet {
|
||||
String[] methods() default {};//允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法
|
||||
|
||||
String comment() default ""; //备注描述
|
||||
|
||||
WebParam[] params() default {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,6 +65,8 @@ public final class Rest {
|
||||
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 webparamDesc = Type.getDescriptor(HttpBaseServlet.WebParam.class);
|
||||
final String sourcetypeDesc = Type.getDescriptor(HttpBaseServlet.ParamSourceType.class);
|
||||
final String serviceTypeString = serviceType.getName().replace('.', '/');
|
||||
final Class userType = getSuperUserType(baseServletClass);
|
||||
|
||||
@@ -215,14 +217,14 @@ public final class Rest {
|
||||
final int maxStack = 3 + params.length;
|
||||
List<int[]> varInsns = new ArrayList<>();
|
||||
int maxLocals = 4;
|
||||
boolean hasVisitWebAction = false;
|
||||
final String jsvar = entry.jsvar.isEmpty() ? null : entry.jsvar;
|
||||
int argIndex = 0;
|
||||
List<Map<String, Object>> paramMaps = new ArrayList<>();
|
||||
|
||||
List<Object[]> paramlist = new ArrayList<>();
|
||||
for (final Parameter param : params) {
|
||||
Map<String, Object> paramMap = new LinkedHashMap<>();
|
||||
final Class ptype = param.getType();
|
||||
String n = null;
|
||||
String comment = "";
|
||||
int radix = 10;
|
||||
RestHeader annhead = null;
|
||||
RestCookie anncookie = null;
|
||||
@@ -232,6 +234,7 @@ public final class Rest {
|
||||
if (annhead != null) {
|
||||
n = annhead.value();
|
||||
radix = annhead.radix();
|
||||
comment = annhead.comment();
|
||||
if (n.isEmpty()) throw new RuntimeException("@RestHeader.value is illegal in " + method);
|
||||
}
|
||||
anncookie = param.getAnnotation(RestCookie.class);
|
||||
@@ -240,6 +243,7 @@ public final class Rest {
|
||||
if (ptype != String.class) throw new RuntimeException("@RestCookie must on String Parameter in " + method);
|
||||
n = anncookie.value();
|
||||
radix = anncookie.radix();
|
||||
comment = anncookie.comment();
|
||||
if (n.isEmpty()) throw new RuntimeException("@RestCookie.value is illegal in " + method);
|
||||
}
|
||||
annaddr = param.getAnnotation(RestAddress.class);
|
||||
@@ -251,8 +255,9 @@ public final class Rest {
|
||||
}
|
||||
RestParam annpara = param.getAnnotation(RestParam.class);
|
||||
if (annpara != null) radix = annpara.radix();
|
||||
if (annpara != null) comment = annpara.comment();
|
||||
if (n == null) n = (annpara == null || annpara.value().isEmpty()) ? null : annpara.value();
|
||||
if (n == null && ptype == userType) n = "_current_user";
|
||||
if (n == null && ptype == userType) n = "&"; //用户类型特殊处理
|
||||
if (n == null) {
|
||||
if (param.isNamePresent()) {
|
||||
n = param.getName();
|
||||
@@ -264,26 +269,64 @@ public final class Rest {
|
||||
&& (entry.name.startsWith("find") || entry.name.startsWith("delete")) && params.length == 1) {
|
||||
if (ptype.isPrimitive() || ptype == String.class) n = "#";
|
||||
}
|
||||
if (!hasVisitWebAction) {
|
||||
hasVisitWebAction = true;
|
||||
//设置 WebAction
|
||||
av0 = mv.visitAnnotation(actionDesc, true);
|
||||
String url = "/" + defmodulename.toLowerCase() + "/" + entry.name + ("#".equals(n) ? "/" : "");
|
||||
av0.visit("url", url);
|
||||
av0.visit("actionid", entry.actionid);
|
||||
|
||||
AnnotationVisitor av1 = av0.visitArray("methods");
|
||||
for (String m : entry.methods) {
|
||||
av1.visit(null, m);
|
||||
paramlist.add(new Object[]{param, n, ptype, radix, comment, annpara, annaddr, annhead, anncookie});
|
||||
}
|
||||
{
|
||||
//设置 WebAction
|
||||
boolean reqpath = false;
|
||||
for (Object[] ps : paramlist) {
|
||||
if ("#".equals((String) ps[1])) {
|
||||
reqpath = true;
|
||||
break;
|
||||
}
|
||||
av1.visitEnd();
|
||||
|
||||
av0.visitEnd();
|
||||
actionMap.put("url", url);
|
||||
actionMap.put("actionid", entry.actionid);
|
||||
actionMap.put("methods", entry.methods);
|
||||
}
|
||||
final String pname = n; //参数名
|
||||
av0 = mv.visitAnnotation(actionDesc, true);
|
||||
String url = "/" + defmodulename.toLowerCase() + "/" + entry.name + (reqpath ? "/" : "");
|
||||
av0.visit("url", url);
|
||||
av0.visit("actionid", entry.actionid);
|
||||
|
||||
AnnotationVisitor av1 = av0.visitArray("methods");
|
||||
for (String m : entry.methods) {
|
||||
av1.visit(null, m);
|
||||
}
|
||||
av1.visitEnd();
|
||||
|
||||
{
|
||||
AnnotationVisitor av3 = av0.visitArray("params");
|
||||
for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, annpara, annaddr, annhead, anncookie}
|
||||
final boolean ishead = ((RestHeader) ps[7]) != null; //是否取getHeader 而不是 getParameter
|
||||
final boolean iscookie = ((RestCookie) ps[8]) != null; //是否取getCookie
|
||||
|
||||
AnnotationVisitor av2 = av3.visitAnnotation(null, webparamDesc);
|
||||
av2.visit("value", (String) ps[1]);
|
||||
av2.visit("type", Type.getType(Type.getDescriptor((Class) ps[2])));
|
||||
av2.visit("radix", (Integer) ps[3]);
|
||||
av2.visitEnum("src", sourcetypeDesc, ishead ? HttpBaseServlet.ParamSourceType.HEADER.name()
|
||||
: (iscookie ? HttpBaseServlet.ParamSourceType.COOKIE.name() : HttpBaseServlet.ParamSourceType.PARAMETER.name()));
|
||||
av2.visit("comment", (String) ps[4]);
|
||||
av2.visitEnd();
|
||||
}
|
||||
av3.visitEnd();
|
||||
}
|
||||
av0.visitEnd();
|
||||
actionMap.put("url", url);
|
||||
actionMap.put("actionid", entry.actionid);
|
||||
actionMap.put("methods", entry.methods);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> paramMaps = new ArrayList<>();
|
||||
for (Object[] ps : paramlist) {
|
||||
Map<String, Object> paramMap = new LinkedHashMap<>();
|
||||
String pname = (String) ps[1]; //参数名
|
||||
Class ptype = (Class) ps[2];
|
||||
int radix = (Integer) ps[3];
|
||||
String comment = (String) ps[4];
|
||||
RestParam annpara = (RestParam) ps[5];
|
||||
RestAddress annaddr = (RestAddress) ps[6];
|
||||
RestHeader annhead = (RestHeader) ps[7];
|
||||
RestCookie anncookie = (RestCookie) ps[8];
|
||||
|
||||
final boolean ishead = annhead != null; //是否取getHeader 而不是 getParameter
|
||||
final boolean iscookie = anncookie != null; //是否取getCookie
|
||||
|
||||
@@ -358,6 +401,12 @@ public final class Rest {
|
||||
} else {
|
||||
throw new RuntimeException(method + " only " + RestParam.class.getSimpleName() + "(#) to Type(primitive class or String)");
|
||||
}
|
||||
} else if ("&".equals(pname) && ptype == userType) { //当前用户对象的类名
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "currentUser", Type.getMethodDescriptor(currentUserMethod), false);
|
||||
mv.visitVarInsn(ASTORE, maxLocals);
|
||||
varInsns.add(new int[]{ALOAD, maxLocals});
|
||||
} else if (ptype == boolean.class) {
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitLdcInsn(pname);
|
||||
@@ -437,12 +486,6 @@ public final class Rest {
|
||||
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "findFlipper", "(Lorg/redkale/net/http/HttpRequest;)Lorg/redkale/source/Flipper;", false);
|
||||
mv.visitVarInsn(ASTORE, maxLocals);
|
||||
varInsns.add(new int[]{ALOAD, maxLocals});
|
||||
} else if (ptype == userType) { //当前用户对象的类名
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "currentUser", Type.getMethodDescriptor(currentUserMethod), false);
|
||||
mv.visitVarInsn(ASTORE, maxLocals);
|
||||
varInsns.add(new int[]{ALOAD, maxLocals});
|
||||
} else { //其他Json对象
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitLdcInsn(Type.getType(Type.getDescriptor(ptype)));
|
||||
@@ -520,27 +563,6 @@ public final class Rest {
|
||||
paramMaps.add(paramMap);
|
||||
} // end params for each
|
||||
|
||||
if (!hasVisitWebAction) { //当无参数时则没有设置过 WebAction
|
||||
hasVisitWebAction = true;
|
||||
//设置 WebAction
|
||||
av0 = mv.visitAnnotation(actionDesc, true);
|
||||
String url = "/" + defmodulename.toLowerCase() + "/" + entry.name;
|
||||
av0.visit("url", url);
|
||||
av0.visit("actionid", entry.actionid);
|
||||
av0.visit("comment", entry.comment);
|
||||
AnnotationVisitor av1 = av0.visitArray("methods");
|
||||
for (String m : entry.methods) {
|
||||
av1.visit(null, m);
|
||||
}
|
||||
av1.visitEnd();
|
||||
av0.visitEnd();
|
||||
|
||||
actionMap.put("url", url);
|
||||
actionMap.put("actionid", entry.actionid);
|
||||
actionMap.put("methods", entry.methods);
|
||||
actionMap.put("comment", entry.comment);
|
||||
}
|
||||
|
||||
//mv.visitVarInsn(ALOAD, 0); //调用this
|
||||
//mv.visitFieldInsn(GETFIELD, newDynName, REST_SERVICE_FIELD_NAME, serviceDesc);
|
||||
mv.visitVarInsn(ALOAD, 3);
|
||||
|
||||
Reference in New Issue
Block a user