This commit is contained in:
Redkale
2016-08-24 21:53:07 +08:00
parent 192e52f18f
commit ce9f517244
9 changed files with 980 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ import java.lang.reflect.*;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.logging.Level;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.net.*;
@@ -84,9 +85,9 @@ public final class NodeHttpServer extends NodeServer {
}, WebSocketNode.class);
}
protected void loadHttpServlet(final AnyValue conf, final ClassFilter<? extends Servlet> filter) throws Exception {
protected void loadHttpServlet(final AnyValue servletsConf, final ClassFilter<? extends Servlet> filter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String prefix = conf == null ? "" : conf.getValue("path", "");
final String prefix = servletsConf == null ? "" : servletsConf.getValue("path", "");
final String threadName = "[" + Thread.currentThread().getName() + "] ";
List<FilterEntry<? extends Servlet>> list = new ArrayList(filter.getFilterEntrys());
list.sort((FilterEntry<? extends Servlet> o1, FilterEntry<? extends Servlet> o2) -> { //必须保证WebSocketServlet优先加载 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
@@ -136,6 +137,85 @@ public final class NodeHttpServer extends NodeServer {
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
loadRestServlet(servletsConf);
}
protected void loadRestServlet(final AnyValue servletsConf) throws Exception {
final String prefix = servletsConf == null ? "" : servletsConf.getValue("path", "");
AnyValue restConf = serverConf == null ? null : serverConf.getAnyValue("rest");
if (restConf == null) return; //不存在REST服务
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>();
final Class<? extends RestHttpServlet> superClass = (Class<? extends RestHttpServlet>) Class.forName(restConf.getValue("servlet", DefaultRestServlet.class.getName()));
final boolean autoload = restConf.getBoolValue("autoload", true);
final boolean mustsign = restConf.getBoolValue("mustsign", false); //是否只加载标记@RestService的Service类
final Pattern[] includes = ClassFilter.toPattern(restConf.getValue("includes", "").split(";"));
final Pattern[] excludes = ClassFilter.toPattern(restConf.getValue("excludes", "").split(";"));
final Set<String> hasServices = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("service")) {
hasServices.add(item.getValue("value", ""));
}
super.interceptorServiceWrappers.forEach((wrapper) -> {
if (!wrapper.getName().isEmpty()) return; //只加载resourceName为空的service
final Class stype = wrapper.getType();
if (mustsign && stype.getAnnotation(RestService.class) == null) return;
final String stypename = stype.getName();
if (stypename.startsWith("org.redkale.")) return;
if (!autoload && !hasServices.contains(stypename)) return;
if (excludes != null && !hasServices.contains(stypename)) {
for (Pattern reg : excludes) {
if (reg.matcher(stypename).matches()) return;
}
}
if (includes != null && !hasServices.contains(stypename)) {
boolean match = false;
for (Pattern reg : includes) {
if (reg.matcher(stypename).matches()) {
match = true;
break;
}
}
if (!match) return;
}
RestHttpServlet servlet = RestServletBuilder.createRestServlet(superClass, wrapper.getName(), stype);
if (servlet == null) return;
try {
Field serviceField = servlet.getClass().getDeclaredField("_service");
serviceField.setAccessible(true);
serviceField.set(servlet, wrapper.getService());
} catch (Exception e) {
throw new RuntimeException(wrapper.getType() + " generate rest servlet error", e);
}
httpServer.addHttpServlet(servlet, prefix, (AnyValue) null);
if (ss != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix + mappings[i];
}
ss.add(new AbstractMap.SimpleEntry<>(servlet.getClass().getName(), mappings));
}
});
//输出信息
if (ss != null && sb != null) {
Collections.sort(ss, (AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
int max = 0;
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
if (as.getKey().length() > max) max = as.getKey().length();
}
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
sb.append(threadName).append(" Loaded ").append(as.getKey());
for (int i = 0; i < max - as.getKey().length(); i++) {
sb.append(' ');
}
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
}

View File

@@ -16,6 +16,7 @@ import java.lang.reflect.Method;
import java.nio.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.*;
import jdk.internal.org.objectweb.asm.*;
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
@@ -30,7 +31,11 @@ import org.redkale.service.RetResult;
*/
public abstract class BasedHttpServlet extends HttpServlet {
public static final int RET_METHOD_ERROR = 1800_0001;
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
public static final int RET_SERVER_ERROR = 1800_0001;
public static final int RET_METHOD_ERROR = 1800_0002;
/**
* 配合 BasedHttpServlet 使用。
@@ -95,6 +100,18 @@ public abstract class BasedHttpServlet extends HttpServlet {
private Map.Entry<String, Entry>[] actions;
/**
* 异常输出
*
* @param req HTTP请求对象
* @param resp HTTP响应对象
* @param exp 异常
*/
protected void sendExceptionResult(HttpRequest req, HttpResponse resp, Throwable exp) {
logger.log(Level.SEVERE, "request = " + req, exp);
resp.finishJson(new RetResult(RET_SERVER_ERROR, "Server Error"));
}
public boolean preExecute(HttpRequest request, HttpResponse response) throws IOException {
return true;
}

View File

@@ -0,0 +1,29 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.io.IOException;
/**
* 默认Servlet, 没有配置RestHttpServlet实现类则使用该默认类
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
public class DefaultRestServlet extends RestHttpServlet<Object> {
@Override
protected Object currentUser(HttpRequest req) throws IOException {
return new Object();
}
@Override
public boolean authenticate(int module, int actionid, HttpRequest request, HttpResponse response) throws IOException {
return true;
}
}

View File

@@ -0,0 +1,21 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.io.IOException;
/**
*
* 详情见: http://redkale.org
*
* @author zhangjx
* @param <T>
*/
public abstract class RestHttpServlet<T> extends BasedHttpServlet {
protected abstract T currentUser(HttpRequest req) throws IOException;
}

View File

@@ -0,0 +1,47 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* 只能依附在Service实现类的public方法上
* value默认为"/" + Service的类名去掉Service字样的小写字符串 (如HelloService的默认路径为/hello)。
* <p>
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({METHOD})
@Retention(RUNTIME)
@Repeatable(RestMappings.class)
public @interface RestMapping {
boolean ignore() default false; //是否屏蔽该方法的转换
/**
* 请求的方法名, 不能含特殊字符
* 默认为方法名的小写(若方法名以createXXX、updateXXX、deleteXXX、queryXXX、findXXX且XXXService为Service的类名将只截取XXX之前)
*
* @return name
*/
String name() default "";
boolean authignore() default true; //是否跳过鉴权,默认跳过
int actionid() default 0; //操作ID值鉴权时用到, 对应&#64;WebAction.actionid
String[] methods() default {};//允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法, 对应&#64;WebAction.methods
String contentType() default ""; //设置Response的ContentType 默认值为 text/plain; charset=utf-8
String jsvar() default ""; //以application/javascript输出对象是指明js的对象名该值存在时则忽略contentType()的值
}

View File

@@ -0,0 +1,26 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* RestMapping 的多用类
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface RestMappings {
RestMapping[] value();
}

View File

@@ -0,0 +1,33 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 只能依附在Service类的方法的参数上
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface RestParam {
String value(); //参数名
/**
* 参数是否从header取 默认使用 request.getJsonParameter 设置为true则使用 request.getJsonHeader 取值
*
* @return 是否从header取
*/
boolean header() default false;
}

View File

@@ -0,0 +1,34 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 只能依附在Service类上value默认为Service的类名去掉Service字样的字符串小写 (如HelloService的默认路径为 hello)。
* <p>
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface RestService {
boolean ignore() default false; //是否屏蔽该类的转换
String value() default ""; //模块名, 只能是模板名,不能含特殊字符
boolean repair() default true; //同&#64;WebServlet的repair属性
int module() default 0; //模块ID值鉴权时用到, 对应&#64;WebServlet.ignore
}

View File

@@ -0,0 +1,690 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import jdk.internal.org.objectweb.asm.*;
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
import jdk.internal.org.objectweb.asm.Type;
import org.redkale.net.sncp.*;
import org.redkale.service.*;
import org.redkale.util.*;
import org.redkale.source.Flipper;
/**
* 以find开头的方法且参数只有一个且参数类型为primitive class或String则RestParam值默认为#
* <p>
* 详情见: http://redkale.org
*
* @author zhangjx
*/
public final class RestServletBuilder {
private static final Set<String> EXCLUDERMETHODS = new HashSet<>();
static {
for (Method m : Object.class.getMethods()) {
EXCLUDERMETHODS.add(m.getName());
}
}
private RestServletBuilder() {
}
//待实现
public static <T extends RestHttpServlet> T createRestServlet(final Class<T> baseServletClass, final String serviceName, final Class<? extends Service> serviceType) {
if (baseServletClass == null || serviceType == null) return null;
if (!RestHttpServlet.class.isAssignableFrom(baseServletClass)) return null;
int mod = baseServletClass.getModifiers();
if (!java.lang.reflect.Modifier.isPublic(mod)) return null;
if (java.lang.reflect.Modifier.isAbstract(mod)) return null;
final String supDynName = baseServletClass.getName().replace('.', '/');
final String serviceDesc = Type.getDescriptor(serviceType);
final String webServletDesc = Type.getDescriptor(WebServlet.class);
final String httpRequestDesc = Type.getDescriptor(HttpRequest.class);
final String httpResponseDesc = Type.getDescriptor(HttpResponse.class);
final String authDesc = Type.getDescriptor(BasedHttpServlet.AuthIgnore.class);
final String actionDesc = Type.getDescriptor(BasedHttpServlet.WebAction.class);
final String serviceTypeString = serviceType.getName().replace('.', '/');
final Class userType = getSuperUserType(baseServletClass);
final RestService controller = serviceType.getAnnotation(RestService.class);
if (controller != null && controller.ignore()) return null; //标记为ignore=true不创建Servlet
ClassLoader loader = Sncp.class.getClassLoader();
String newDynName = serviceTypeString.substring(0, serviceTypeString.lastIndexOf('/') + 1) + "_Dyn" + serviceType.getSimpleName().replaceAll("Service.*$", "") + "RestServlet";
if (!serviceName.isEmpty()) {
boolean normal = true;
for (char ch : serviceName.toCharArray()) {//含特殊字符的使用hash值
if (!((ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) normal = false;
}
newDynName += "_" + (normal ? serviceName : Sncp.hash(serviceName));
}
try {
return ((Class<T>) Class.forName(newDynName.replace('/', '.'))).newInstance();
} catch (Exception ex) {
}
Method currentUserMethod = null;
try {
currentUserMethod = baseServletClass.getDeclaredMethod("currentUser", HttpRequest.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
//------------------------------------------------------------------------------
final String defmodulename = (controller != null && !controller.value().isEmpty()) ? controller.value() : serviceType.getSimpleName().replaceAll("Service.*$", "");
for (char ch : defmodulename.toCharArray()) {
if (!((ch >= '0' && ch <= '9') || ch == '$' || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) { //不能含特殊字符
throw new RuntimeException(serviceType.getName() + " has illeal " + RestService.class.getSimpleName() + ".value, only 0-9 a-z A-Z _ $");
}
}
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
FieldVisitor fv;
AsmMethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null);
{ //注入 @WebServlet 注解
av0 = cw.visitAnnotation(webServletDesc, true);
{
AnnotationVisitor av1 = av0.visitArray("value");
av1.visit(null, "/" + defmodulename.toLowerCase() + "/*");
av1.visitEnd();
}
av0.visit("moduleid", controller == null ? 0 : controller.module());
av0.visit("repair", controller == null ? true : controller.repair());
av0.visitEnd();
}
{ //注入 @Resource private XXXService _service;
fv = cw.visitField(ACC_PRIVATE, "_service", serviceDesc, null, null);
av0 = fv.visitAnnotation("Ljavax/annotation/Resource;", true);
av0.visitEnd();
fv.visitEnd();
}
{ //构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
//mv.setDebug(true);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
final List<MappingEntry> entrys = new ArrayList<>();
for (final Method method : serviceType.getMethods()) {
Class[] extypes = method.getExceptionTypes();
if (extypes.length > 1) continue;
if (extypes.length == 1 && extypes[0] != IOException.class) continue;
if (EXCLUDERMETHODS.contains(method.getName())) continue;
if ("init".equals(method.getName())) continue;
if ("destroy".equals(method.getName())) continue;
RestMapping[] mappings = method.getAnnotationsByType(RestMapping.class);
boolean ignore = false;
for (RestMapping mapping : mappings) {
if (mapping.ignore()) {
ignore = true;
break;
}
}
if (ignore) continue;
if (mappings.length == 0) { //没有Mapping设置一个默认值
MappingEntry entry = new MappingEntry(null, defmodulename, method);
if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
entrys.add(entry);
} else {
for (RestMapping mapping : mappings) {
MappingEntry entry = new MappingEntry(mapping, defmodulename, method);
if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
entrys.add(entry);
}
}
}
if (entrys.isEmpty()) return null;
for (final MappingEntry entry : entrys) {
final Method method = entry.mappingMethod;
final Class returnType = method.getReturnType();
final String methodDesc = Type.getMethodDescriptor(method);
final Parameter[] params = method.getParameters();
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, entry.name, "(" + httpRequestDesc + httpResponseDesc + ")V", null, new String[]{"java/io/IOException"}));
//mv.setDebug(true);
mv.debugLine();
if (entry.authignore) { //设置 AuthIgnore
av0 = mv.visitAnnotation(authDesc, true);
av0.visitEnd();
}
final int maxStack = 3 + params.length;
List<int[]> varInsns = new ArrayList<>();
int maxLocals = 3;
boolean hasVisitWebAction = false;
final String jsvar = entry.jsvar.isEmpty() ? null : entry.jsvar;
int argIndex = 0;
for (final Parameter param : params) {
final Class ptype = param.getType();
RestParam annpara = param.getAnnotation(RestParam.class);
String n = annpara == null || annpara.value().isEmpty() ? null : annpara.value();
if (n == null) {
if (param.isNamePresent()) {
n = param.getName();
} else {
n = (++argIndex > 1) ? ("bean" + argIndex) : "bean";
}
}
if ((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);
av0.visit("url", "/" + defmodulename.toLowerCase() + "/" + entry.name + ("#".equals(n) ? "/" : ""));
av0.visit("actionid", entry.actionid);
AnnotationVisitor av1 = av0.visitArray("methods");
for (String m : entry.methods) {
av1.visit(null, m);
}
av1.visitEnd();
av0.visitEnd();
}
final String pname = n;
final boolean hd = annpara == null ? false : annpara.header();
if ("#".equals(pname)) { //从request.getRequstURI 中去参数
if (ptype == boolean.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "parseBoolean", "(Ljava/lang/String;)Z", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == byte.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "parseByte", "(Ljava/lang/String;)B", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == short.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "parseShort", "(Ljava/lang/String;)S", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == char.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == int.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == float.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "parseFloat", "(Ljava/lang/String;)F", false);
mv.visitVarInsn(FSTORE, maxLocals);
varInsns.add(new int[]{FLOAD, maxLocals});
} else if (ptype == long.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "parseLong", "(Ljava/lang/String;)J", false);
mv.visitVarInsn(LSTORE, maxLocals);
varInsns.add(new int[]{LLOAD, maxLocals});
maxLocals++;
} else if (ptype == double.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "parseDouble", "(Ljava/lang/String;)D", false);
mv.visitVarInsn(DSTORE, maxLocals);
varInsns.add(new int[]{DLOAD, maxLocals});
maxLocals++;
} else if (ptype == String.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getRequstURILastPath", "()Ljava/lang/String;", false);
mv.visitVarInsn(ASTORE, maxLocals);
} else {
throw new RuntimeException(method + " only " + RestParam.class.getSimpleName() + "(#) to Type(primitive class or String)");
}
} else if (ptype == boolean.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getBooleanHeader" : "getBooleanParameter", "(Ljava/lang/String;Z)Z", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == byte.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitLdcInsn("0");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getHeader" : "getParameter", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "parseByte", "(Ljava/lang/String;)B", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == short.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getShortHeader" : "getShortParameter", "(Ljava/lang/String;S)S", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == char.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitLdcInsn("0");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getHeader" : "getParameter", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == int.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getIntHeader" : "getIntParameter", "(Ljava/lang/String;I)I", false);
mv.visitVarInsn(ISTORE, maxLocals);
varInsns.add(new int[]{ILOAD, maxLocals});
} else if (ptype == float.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(FCONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getFloatHeader" : "getFloatParameter", "(Ljava/lang/String;F)F", false);
mv.visitVarInsn(FSTORE, maxLocals);
varInsns.add(new int[]{FLOAD, maxLocals});
} else if (ptype == long.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(LCONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getLongHeader" : "getLongParameter", "(Ljava/lang/String;J)J", false);
mv.visitVarInsn(LSTORE, maxLocals);
varInsns.add(new int[]{LLOAD, maxLocals});
maxLocals++;
} else if (ptype == double.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitInsn(DCONST_0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getDoubleHeader" : "getDoubleParameter", "(Ljava/lang/String;D)D", false);
mv.visitVarInsn(DSTORE, maxLocals);
varInsns.add(new int[]{DLOAD, maxLocals});
maxLocals++;
} else if (ptype == String.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(pname);
mv.visitLdcInsn("");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getHeader" : "getParameter", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
mv.visitVarInsn(ASTORE, maxLocals);
varInsns.add(new int[]{ALOAD, maxLocals});
} else if (ptype == Flipper.class) {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", "getFlipper", "()Lorg/redkale/source/Flipper;", false);
//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 {
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(Type.getType(Type.getDescriptor(ptype)));
mv.visitLdcInsn(pname);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpRequest", hd ? "getJsonHeader" : "getJsonParameter", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, ptype.getName().replace('.', '/'));
mv.visitVarInsn(ASTORE, maxLocals);
varInsns.add(new int[]{ALOAD, maxLocals});
}
maxLocals++;
} // end params for each
if (!hasVisitWebAction) { //当无参数时则没有设置过 WebAction
hasVisitWebAction = true;
//设置 WebAction
av0 = mv.visitAnnotation(actionDesc, true);
av0.visit("url", "/" + defmodulename.toLowerCase() + "/" + entry.name);
av0.visit("actionid", entry.actionid);
av0.visitEnd();
}
mv.visitVarInsn(ALOAD, 0); //调用this
mv.visitFieldInsn(GETFIELD, newDynName, "_service", serviceDesc);
for (int[] ins : varInsns) {
mv.visitVarInsn(ins[0], ins[1]);
}
mv.visitMethodInsn(INVOKEVIRTUAL, serviceTypeString, method.getName(), methodDesc, false);
if (returnType == void.class) {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
//mv.visitFieldInsn(GETSTATIC, "org/redkale/service/RetResult", "SUCCESS", "Lorg/redkale/service/RetResult;");
mv.visitMethodInsn(INVOKESTATIC, "org/redkale/service/RetResult", "success", "()Lorg/redkale/service/RetResult;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJson", "(Lorg/redkale/service/RetResult;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendRetResult", "(Lorg/redkale/net/http/HttpResponse;Lorg/redkale/service/RetResult;)V", false);
mv.visitInsn(RETURN);
} else if (returnType == boolean.class) {
mv.visitVarInsn(ISTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Z)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == byte.class) {
mv.visitVarInsn(ISTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(I)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == short.class) {
mv.visitVarInsn(ISTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(I)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == char.class) {
mv.visitVarInsn(ISTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(C)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == int.class) {
mv.visitVarInsn(ISTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(I)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ILOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == float.class) {
mv.visitVarInsn(FSTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(FLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(F)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(FLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == long.class) {
mv.visitVarInsn(LSTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(LLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(J)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(LLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals += 2;
} else if (returnType == double.class) {
mv.visitVarInsn(DSTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(DLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(D)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(DLOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals += 2;
} else if (returnType == String.class) {
mv.visitVarInsn(ASTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (returnType == File.class) {
mv.visitVarInsn(ASTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/io/File;)V", false);
} else {
throw new RuntimeException(method + " cannot set return Type (java.io.File) to jsvar");
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (RetResult.class.isAssignableFrom(returnType)) {
mv.visitVarInsn(ASTORE, maxLocals);
if (jsvar == null) {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJson", "(Lorg/redkale/service/RetResult;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendRetResult", "(Lorg/redkale/net/http/HttpResponse;Lorg/redkale/service/RetResult;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else if (Number.class.isAssignableFrom(returnType) || CharSequence.class.isAssignableFrom(returnType)) { //returnType == String.class 必须放在前面
mv.visitVarInsn(ASTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finish", "(Ljava/lang/String;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
} else {
mv.visitVarInsn(ASTORE, maxLocals);
if (jsvar == null) {
mv.visitVarInsn(ALOAD, 2); //response
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJson", "(Ljava/lang/Object;)V", false);
} else {
//mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(jsvar);
mv.visitVarInsn(ALOAD, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/net/http/HttpResponse", "finishJsResult", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
//mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "sendJsResult", "(Lorg/redkale/net/http/HttpResponse;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
mv.visitInsn(RETURN);
maxLocals++;
}
mv.visitMaxs(maxStack, maxLocals);
} // end for each
cw.visitEnd();
byte[] bytes = cw.toByteArray();
Class<?> newClazz = new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass(newDynName.replace('/', '.'), bytes);
try {
return ((Class<T>) newClazz).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Class getSuperUserType(Class servletClass) {
java.lang.reflect.Type type = servletClass.getGenericSuperclass();
if (type instanceof Class) return getSuperUserType((Class) type);
if (type instanceof java.lang.reflect.ParameterizedType) {
java.lang.reflect.ParameterizedType pt = (java.lang.reflect.ParameterizedType) type;
if (pt.getRawType() == RestHttpServlet.class) {
java.lang.reflect.Type usert = pt.getActualTypeArguments()[0];
if (usert instanceof Class) return (Class) usert;
}
}
return null;
}
private static class MappingEntry {
private static final RestMapping DEFAULT__MAPPING;
static {
try {
DEFAULT__MAPPING = MappingEntry.class.getDeclaredMethod("mapping").getAnnotation(RestMapping.class);
} catch (Exception e) {
throw new Error(e);
}
}
public MappingEntry(RestMapping mapping, final String defmodulename, Method method) {
if (mapping == null) mapping = DEFAULT__MAPPING;
this.ignore = mapping.ignore();
String n = mapping.name().toLowerCase();
if (n.isEmpty()) n = method.getName().toLowerCase().replace(defmodulename.toLowerCase(), "");
this.name = n;
this.mappingMethod = method;
this.methods = mapping.methods();
this.authignore = mapping.authignore();
this.actionid = mapping.actionid();
this.contentType = mapping.contentType();
this.jsvar = mapping.jsvar();
}
public final Method mappingMethod;
public final boolean ignore;
public final String name;
public final String[] methods;
public final boolean authignore;
public final int actionid;
public final String contentType;
public final String jsvar;
@RestMapping()
void mapping() { //用于获取Mapping 默认值
}
@Override
public int hashCode() {
return this.name.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return this.name.equals(((MappingEntry) obj).name);
}
}
}