diff --git a/src/org/redkale/boot/ApiDocs.java b/src/org/redkale/boot/ApiDocs.java index ae160afe9..425c76e02 100644 --- a/src/org/redkale/boot/ApiDocs.java +++ b/src/org/redkale/boot/ApiDocs.java @@ -16,7 +16,7 @@ import org.redkale.util.*; /** * API接口文档生成类,作用:生成Application实例中所有HttpServer的可用HttpServlet的API接口方法
- * 继承 HttpBaseServlet 是为了获取 WebAction 信息 + 继承 HttpBaseServlet 是为了获取 WebMapping 信息 * *

* 详情见: https://redkale.org @@ -63,8 +63,8 @@ public class ApiDocs extends HttpBaseServlet { servletmap.put("name", ws.name()); servletmap.put("comment", ws.comment()); - List actionsList = new ArrayList<>(); - servletmap.put("actions", actionsList); + List mappingsList = new ArrayList<>(); + servletmap.put("mappings", mappingsList); final Class selfClz = servlet.getClass(); Class clz = servlet.getClass(); HashSet actionurls = new HashSet<>(); @@ -72,18 +72,18 @@ public class ApiDocs extends HttpBaseServlet { if (Modifier.isAbstract(clz.getModifiers())) break; for (Method method : clz.getMethods()) { if (method.getParameterCount() != 2) continue; - WebAction action = method.getAnnotation(WebAction.class); + WebMapping action = method.getAnnotation(WebMapping.class); if (action == null) continue; if (!action.inherited() && selfClz != clz) continue; //忽略不被继承的方法 - final Map actionmap = new LinkedHashMap<>(); + final Map mappingmap = new LinkedHashMap<>(); if (actionurls.contains(action.url())) continue; - actionmap.put("url", prefix + action.url()); + mappingmap.put("url", prefix + action.url()); actionurls.add(action.url()); - actionmap.put("auth", method.getAnnotation(AuthIgnore.class) == null); - actionmap.put("actionid", action.actionid()); - actionmap.put("comment", action.comment()); + mappingmap.put("auth", method.getAnnotation(AuthIgnore.class) == null); + mappingmap.put("actionid", action.actionid()); + mappingmap.put("comment", action.comment()); List paramsList = new ArrayList<>(); - actionmap.put("params", paramsList); + mappingmap.put("params", paramsList); List results = new ArrayList<>(); for (final Class rtype : action.results()) { results.add(rtype.getName()); @@ -121,7 +121,7 @@ public class ApiDocs extends HttpBaseServlet { } while ((loop = loop.getSuperclass()) != Object.class); typesmap.put(rtype.getName(), typemap); } - actionmap.put("results", results); + mappingmap.put("results", results); for (WebParam param : method.getAnnotationsByType(WebParam.class)) { final Map parammap = new LinkedHashMap<>(); final boolean isarray = param.type().isArray(); @@ -171,11 +171,11 @@ public class ApiDocs extends HttpBaseServlet { typesmap.put(ptype.getName(), typemap); } - actionmap.put("result", action.result()); - actionsList.add(actionmap); + mappingmap.put("result", action.result()); + mappingsList.add(mappingmap); } } while ((clz = clz.getSuperclass()) != HttpServlet.class); - actionsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url"))); + mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url"))); servletsList.add(servletmap); } servletsList.sort((o1, o2) -> { diff --git a/src/org/redkale/boot/apidoc-template.html b/src/org/redkale/boot/apidoc-template.html index abdf6ed1c..5c7f99680 100644 --- a/src/org/redkale/boot/apidoc-template.html +++ b/src/org/redkale/boot/apidoc-template.html @@ -36,8 +36,8 @@ if (html.length > 2) html.push('  '); html.push(' ' + (servlet.comment || '未知模块') + ''); html.push(' 请求URL描 述鉴 权参 数 (粗体: 必填项; 红色: Header; 蓝色: Cookie)输 出'); - for (var k = 0; k < servlet.actions.length; k++) { - var action = servlet.actions[k]; + for (var k = 0; k < servlet.mappings.length; k++) { + var action = servlet.mappings[k]; html.push(' '); html.push('' + action.url + ''); html.push('' + action.comment + ''); diff --git a/src/org/redkale/net/http/HttpBaseServlet.java b/src/org/redkale/net/http/HttpBaseServlet.java index b4dec65c6..cfff21c13 100644 --- a/src/org/redkale/net/http/HttpBaseServlet.java +++ b/src/org/redkale/net/http/HttpBaseServlet.java @@ -66,8 +66,8 @@ public abstract class HttpBaseServlet extends HttpServlet { } /** - * 配合 @WebAction 使用。 - * 用于对@WebAction方法中参数描述 + * 配合 @WebMapping 使用。 + * 用于对@WebMapping方法中参数描述 * *

* 详情见: https://redkale.org @@ -101,6 +101,34 @@ public abstract class HttpBaseServlet extends HttpServlet { WebParam[] value(); } + /** + * 使用 WebMapping 替代。 + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + */ + @Deprecated + @Documented + @Target({METHOD}) + @Retention(RUNTIME) + protected @interface WebAction { + + int actionid() default 0; + + String url(); + + String[] methods() default {};//允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法 + + String comment() default ""; //备注描述 + + boolean inherited() default true; //是否能被继承, 当 HttpBaseServlet 被继承后该方法是否能被子类继承 + + String result() default "Object"; //输出结果的数据类型 + + Class[] results() default {}; //输出结果的数据类型集合,由于结果类型可能是泛型而注解的参数值不支持泛型,因此加入明细数据类型集合 + } + /** * 配合 HttpBaseServlet 使用。 * 用于对@WebServlet对应的url进行细分。 其url必须是包含WebServlet中定义的前缀, 且不能是正则表达式 @@ -113,7 +141,7 @@ public abstract class HttpBaseServlet extends HttpServlet { @Documented @Target({METHOD}) @Retention(RUNTIME) - protected @interface WebAction { + protected @interface WebMapping { int actionid() default 0; @@ -153,7 +181,7 @@ public abstract class HttpBaseServlet extends HttpServlet { int seconds() default 15; } - private Map.Entry[] actions; + private Map.Entry[] mappings; public boolean preExecute(HttpRequest request, HttpResponse response) throws IOException { return true; @@ -162,7 +190,7 @@ public abstract class HttpBaseServlet extends HttpServlet { @Override public final void execute(HttpRequest request, HttpResponse response) throws IOException { if (!preExecute(request, response)) return; - for (Map.Entry en : actions) { + for (Map.Entry en : mappings) { if (request.getRequestURI().startsWith(en.getKey())) { Entry entry = en.getValue(); if (!entry.checkMethod(request.getMethod())) { @@ -193,13 +221,13 @@ public abstract class HttpBaseServlet extends HttpServlet { WebServlet ws = this.getClass().getAnnotation(WebServlet.class); if (ws != null && !ws.repair()) path = ""; HashMap map = load(); - this.actions = new Map.Entry[map.size()]; + this.mappings = new Map.Entry[map.size()]; int i = -1; for (Map.Entry en : map.entrySet()) { - actions[++i] = new AbstractMap.SimpleEntry<>(path + en.getKey(), en.getValue()); + mappings[++i] = new AbstractMap.SimpleEntry<>(path + en.getKey(), en.getValue()); } //必须要倒排序, /query /query1 /query12 确保含子集的优先匹配 /query12 /query1 /query - Arrays.sort(actions, (o1, o2) -> o2.getKey().compareTo(o1.getKey())); + Arrays.sort(mappings, (o1, o2) -> o2.getKey().compareTo(o1.getKey())); } public final void postDestroy(HttpContext context, AnyValue config) { @@ -242,17 +270,20 @@ public abstract class HttpBaseServlet extends HttpServlet { if (exps.length > 0 && (exps.length != 1 || exps[0] != IOException.class)) continue; //----------------------------------------------- + final WebMapping mapping = method.getAnnotation(WebMapping.class); final WebAction action = method.getAnnotation(WebAction.class); - if (action == null) continue; - if (!action.inherited() && selfClz != clz) continue; //忽略不被继承的方法 - final int actionid = action.actionid(); - final String name = action.url().trim(); + if (mapping == null && action == null) continue; + final boolean inherited = action == null ? action.inherited() : mapping.inherited(); + if (!inherited && selfClz != clz) continue; //忽略不被继承的方法 + final int actionid = action == null ? action.actionid() : mapping.actionid(); + final String name = action == null ? action.url().trim() : mapping.url().trim(); + final String[] methods = action == null ? action.methods() : mapping.methods(); if (nameset.containsKey(name)) { if (nameset.get(name) != clz) continue; - throw new RuntimeException(this.getClass().getSimpleName() + " has two same " + WebAction.class.getSimpleName() + "(" + name + ")"); + throw new RuntimeException(this.getClass().getSimpleName() + " has two same " + WebMapping.class.getSimpleName() + "(" + name + ")"); } nameset.put(name, clz); - map.put(name, new Entry(typeIgnore, serviceid, actionid, name, action.methods(), method, createHttpServlet(method))); + map.put(name, new Entry(typeIgnore, serviceid, actionid, name, methods, method, createHttpServlet(method))); } } while ((clz = clz.getSuperclass()) != HttpBaseServlet.class); return map; diff --git a/src/org/redkale/net/http/Rest.java b/src/org/redkale/net/http/Rest.java index a87ce4f76..1b341730e 100644 --- a/src/org/redkale/net/http/Rest.java +++ b/src/org/redkale/net/http/Rest.java @@ -82,7 +82,7 @@ public final class Rest { final String attrDesc = Type.getDescriptor(org.redkale.util.Attribute.class); final String authDesc = Type.getDescriptor(HttpBaseServlet.AuthIgnore.class); final String cacheDesc = Type.getDescriptor(HttpBaseServlet.HttpCacheable.class); - final String actionDesc = Type.getDescriptor(HttpBaseServlet.WebAction.class); + final String mappingDesc = Type.getDescriptor(HttpBaseServlet.WebMapping.class); final String webparamDesc = Type.getDescriptor(HttpBaseServlet.WebParam.class); final String webparamsDesc = Type.getDescriptor(HttpBaseServlet.WebParams.class); final String sourcetypeDesc = Type.getDescriptor(HttpBaseServlet.ParamSourceType.class); @@ -122,7 +122,7 @@ public final class Rest { AsmMethodVisitor mv; AnnotationVisitor av0; Map classMap = new LinkedHashMap<>(); - List> actionMaps = new ArrayList<>(); + List> mappingMaps = new ArrayList<>(); cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); { //RestDynamic @@ -207,7 +207,7 @@ public final class Rest { } } } - if (entrys.isEmpty()) return null; //没有可WebAction的方法 + if (entrys.isEmpty()) return null; //没有可WebMapping的方法 for (final MappingEntry entry : entrys) { final Method method = entry.mappingMethod; final Class returnType = method.getReturnType(); @@ -316,9 +316,9 @@ public final class Rest { paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie}); } - Map actionMap = new LinkedHashMap<>(); + Map mappingMap = new LinkedHashMap<>(); { - //设置 WebAction + //设置 WebMapping boolean reqpath = false; for (Object[] ps : paramlist) { if ("#".equals((String) ps[1])) { @@ -326,7 +326,7 @@ public final class Rest { break; } } - av0 = mv.visitAnnotation(actionDesc, true); + av0 = mv.visitAnnotation(mappingDesc, true); String url = "/" + defmodulename.toLowerCase() + "/" + entry.name + (reqpath ? "/" : ""); av0.visit("url", url); av0.visit("actionid", entry.actionid); @@ -342,13 +342,13 @@ public final class Rest { av0.visit("result", grt == returnType ? returnType.getName() : String.valueOf(grt)); av0.visitEnd(); - actionMap.put("url", url); - actionMap.put("auth", entry.auth); - actionMap.put("cachetimeout", entry.cacheseconds); - actionMap.put("actionid", entry.actionid); - actionMap.put("comment", entry.comment); - actionMap.put("methods", entry.methods); - actionMap.put("result", grt == returnType ? returnType.getName() : String.valueOf(grt)); + mappingMap.put("url", url); + mappingMap.put("auth", entry.auth); + mappingMap.put("cachetimeout", entry.cacheseconds); + mappingMap.put("actionid", entry.actionid); + mappingMap.put("comment", entry.comment); + mappingMap.put("methods", entry.methods); + mappingMap.put("result", grt == returnType ? returnType.getName() : String.valueOf(grt)); } { @@ -838,8 +838,8 @@ public final class Rest { maxLocals++; } mv.visitMaxs(maxStack, maxLocals); - actionMap.put("params", paramMaps); - actionMaps.add(actionMap); + mappingMap.put("params", paramMaps); + mappingMaps.add(mappingMap); } // end for each for (String attrname : restAttributes.keySet()) { @@ -847,7 +847,7 @@ public final class Rest { fv.visitEnd(); } - classMap.put("actions", actionMaps); + classMap.put("mappings", mappingMaps); { //toString函数 mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null)); diff --git a/src/org/redkale/net/http/RestMapping.java b/src/org/redkale/net/http/RestMapping.java index afb44ef28..daaec57d3 100644 --- a/src/org/redkale/net/http/RestMapping.java +++ b/src/org/redkale/net/http/RestMapping.java @@ -40,7 +40,7 @@ public @interface RestMapping { String name() default ""; /** - * 备注描述, 对应@WebAction.comment + * 备注描述, 对应@WebMapping.comment * * @return String */ @@ -54,7 +54,7 @@ public @interface RestMapping { boolean auth() default false; /** - * 操作ID值,鉴权时用到, 对应@WebAction.actionid + * 操作ID值,鉴权时用到, 对应@WebMapping.actionid * * @return int */ @@ -68,7 +68,7 @@ public @interface RestMapping { int cacheseconds() default 0; /** - * 允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法, 对应@WebAction.methods + * 允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法, 对应@WebMapping.methods * * @return String[] */ diff --git a/test/org/redkale/test/rest/_DynHelloRestServlet1.java b/test/org/redkale/test/rest/_DynHelloRestServlet1.java index 16e590e80..5f25a99de 100644 --- a/test/org/redkale/test/rest/_DynHelloRestServlet1.java +++ b/test/org/redkale/test/rest/_DynHelloRestServlet1.java @@ -42,7 +42,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/create") + @WebMapping(url = "/hello/create") public void create(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean"); @@ -54,7 +54,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/delete/") + @WebMapping(url = "/hello/delete/") public void delete(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); int id = Integer.parseInt(req.getRequstURILastPath()); @@ -63,7 +63,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/update") + @WebMapping(url = "/hello/update") public void update(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); String clientaddr = req.getRemoteAddr(); @@ -75,7 +75,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/partupdate") + @WebMapping(url = "/hello/partupdate") public void partupdate(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean"); @@ -87,7 +87,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/query") + @WebMapping(url = "/hello/query") public void query(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); HelloBean bean = req.getJsonParameter(HelloBean.class, "bean"); @@ -101,7 +101,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/list") + @WebMapping(url = "/hello/list") public void list(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); HelloBean bean = req.getJsonParameter(HelloBean.class, "bean"); @@ -114,7 +114,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/find/") + @WebMapping(url = "/hello/find/") public void find(HttpRequest req, HttpResponse resp) throws IOException { HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); int id = Integer.parseInt(req.getRequstURILastPath()); diff --git a/test/org/redkale/test/rest/_DynHelloRestServlet2.java b/test/org/redkale/test/rest/_DynHelloRestServlet2.java index 5b5ec24d6..23db0f9f0 100644 --- a/test/org/redkale/test/rest/_DynHelloRestServlet2.java +++ b/test/org/redkale/test/rest/_DynHelloRestServlet2.java @@ -27,7 +27,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { private Map _servicemap; @AuthIgnore - @WebAction(url = "/hello/create", comment = "创建Hello对象") + @WebMapping(url = "/hello/create", comment = "创建Hello对象") @WebParam(name = "bean", type = HelloEntity.class, comment = "Hello对象") public void create(HttpRequest req, HttpResponse resp) throws IOException { HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); @@ -40,7 +40,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/delete/", comment = "根据id删除Hello对象") + @WebMapping(url = "/hello/delete/", comment = "根据id删除Hello对象") @WebParam(name = "#", type = int.class, comment = "Hello对象id") public void delete(HttpRequest req, HttpResponse resp) throws IOException { HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); @@ -50,7 +50,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/update", comment = "修改Hello对象") + @WebMapping(url = "/hello/update", comment = "修改Hello对象") @WebParam(name = "bean", type = HelloEntity.class, comment = "Hello对象") public void update(HttpRequest req, HttpResponse resp) throws IOException { HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); @@ -62,7 +62,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/query", comment = "查询Hello对象列表") + @WebMapping(url = "/hello/query", comment = "查询Hello对象列表") @WebParam(name = "bean", type = HelloBean.class, comment = "过滤条件") public void query(HttpRequest req, HttpResponse resp) throws IOException { HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, "")); @@ -77,7 +77,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { } @AuthIgnore - @WebAction(url = "/hello/find/", comment = "根据id删除Hello对象") + @WebMapping(url = "/hello/find/", comment = "根据id删除Hello对象") @WebParam(name = "#", type = int.class, comment = "Hello对象id") public void find(HttpRequest req, HttpResponse resp) throws IOException { HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));