diff --git a/src/org/redkale/boot/ApiDocsService.java b/src/org/redkale/boot/ApiDocsService.java index 77aec1f26..612218cbc 100644 --- a/src/org/redkale/boot/ApiDocsService.java +++ b/src/org/redkale/boot/ApiDocsService.java @@ -113,7 +113,7 @@ public final class ApiDocsService { } fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null)); fieldmap.put("updatable", (filter || col == null || col.updatable())); - if (servlet.getClass().getAnnotation(Rest.RestDynamic.class) != null) { + if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) { if (field.getAnnotation(RestAddress.class) != null) continue; } @@ -162,7 +162,7 @@ public final class ApiDocsService { fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null)); fieldmap.put("updatable", (filter || col == null || col.updatable())); - if (servlet.getClass().getAnnotation(Rest.RestDynamic.class) != null) { + if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) { if (field.getAnnotation(RestAddress.class) != null) continue; } diff --git a/src/org/redkale/boot/NodeHttpServer.java b/src/org/redkale/boot/NodeHttpServer.java index fb7ea0560..db13c3947 100644 --- a/src/org/redkale/boot/NodeHttpServer.java +++ b/src/org/redkale/boot/NodeHttpServer.java @@ -239,7 +239,7 @@ public class NodeHttpServer extends NodeServer { return; } restedObjects.add(service); //避免重复创建Rest对象 - HttpServlet servlet = httpServer.addRestServlet(name, stype, service, userType, baseServletType, prefix, (AnyValue) null); + HttpServlet servlet = httpServer.addRestServlet(service, userType, baseServletType, prefix); if (servlet == null) return; //没有HttpMapping方法的HttpServlet调用Rest.createRestServlet就会返回null resourceFactory.inject(servlet, NodeHttpServer.this); if (finest) logger.finest(threadName + " Create RestServlet(resource.name='" + name + "') = " + servlet); diff --git a/src/org/redkale/net/http/HttpPrepareServlet.java b/src/org/redkale/net/http/HttpPrepareServlet.java index 2219545a5..48dc0063e 100644 --- a/src/org/redkale/net/http/HttpPrepareServlet.java +++ b/src/org/redkale/net/http/HttpPrepareServlet.java @@ -13,6 +13,7 @@ import java.util.logging.*; import java.util.regex.*; import org.redkale.net.*; import org.redkale.net.http.Rest.RestDynSourceType; +import org.redkale.service.Service; import org.redkale.util.*; /** @@ -96,35 +97,49 @@ public class HttpPrepareServlet extends PrepareServlet List removeHttpServlet(final Class servletOrServiceOrWsType) { + public HttpServlet removeHttpServlet(Service service) { + Predicate predicateEntry = (t) -> { + if (!Rest.isRestDyn(t.servlet)) return false; + Service s = Rest.getService(t.servlet); + if (s == service) return true; + if (s != null) return false; + Map map = Rest.getServiceMap(t.servlet); + if (map == null) return false; + boolean rs = map.values().contains(service); + if (rs && map.size() == 1) return true; + if (rs && map.size() > 1) { + String key = null; + for (Map.Entry en : map.entrySet()) { + if (en.getValue() == service) { + key = en.getKey(); + break; + } + } + if (key != null) map.remove(key); + return false; //还有其他Resouce.name 的Service + } + return rs; + }; + Predicate> predicateFilter = null; + List list = removeHttpServlet(predicateEntry, predicateFilter); + return list == null || list.isEmpty() ? null : list.get(0); + } + + public HttpServlet removeHttpServlet(Class websocketOrServletType) { Predicate predicateEntry = (t) -> { Class type = t.servlet.getClass(); - if (type == servletOrServiceOrWsType) return true; + if (type == websocketOrServletType) return true; RestDynSourceType rdt = (RestDynSourceType) type.getAnnotation(RestDynSourceType.class); - return (rdt != null && rdt.value() == servletOrServiceOrWsType); + return (rdt != null && rdt.value() == websocketOrServletType); }; Predicate> predicateFilter = (t) -> { Class type = t.getValue().getClass(); - if (type == servletOrServiceOrWsType) return true; + if (type == websocketOrServletType) return true; RestDynSourceType rdt = (RestDynSourceType) type.getAnnotation(RestDynSourceType.class); - return (rdt != null && rdt.value() == servletOrServiceOrWsType); + return (rdt != null && rdt.value() == websocketOrServletType); }; - return removeHttpServlet(predicateEntry, predicateFilter); - } - - public List removeHttpServlet(String mapping0) { - if (Utility.contains(mapping0, '.', '*', '{', '[', '(', '|', '^', '$', '+', '?', '\\')) { //是否是正则表达式)) - if (mapping0.charAt(0) != '^') mapping0 = '^' + mapping0; - if (mapping0.endsWith("/*")) { - mapping0 = mapping0.substring(0, mapping0.length() - 1) + ".*"; - } else { - mapping0 = mapping0 + "$"; - } - } - final String mapping = mapping0; - Predicate predicateEntry = (t) -> t.mapping.equals(mapping); - Predicate> predicateFilter = (t) -> t.getKey().equals(mapping); - return removeHttpServlet(predicateEntry, predicateFilter); + List list = removeHttpServlet(predicateEntry, predicateFilter); + return list == null || list.isEmpty() ? null : list.get(0); } public boolean addForbidURIReg(final String urlreg) { diff --git a/src/org/redkale/net/http/HttpServer.java b/src/org/redkale/net/http/HttpServer.java index ce838f955..339067a36 100644 --- a/src/org/redkale/net/http/HttpServer.java +++ b/src/org/redkale/net/http/HttpServer.java @@ -11,6 +11,7 @@ import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.atomic.AtomicLong; import org.redkale.net.*; +import org.redkale.net.sncp.Sncp; import org.redkale.service.Service; import org.redkale.util.*; @@ -60,34 +61,23 @@ public class HttpServer extends Server removeHttpServlet(Class servletOrServiceOrWsType) { - return ((HttpPrepareServlet) this.prepare).removeHttpServlet(servletOrServiceOrWsType); - } - - /** - * 删除HttpServlet - * - * @param mapping String - * - * @return HttpServlet - */ - public List removeHttpServlet(String mapping) { - return ((HttpPrepareServlet) this.prepare).removeHttpServlet(mapping); + public HttpServlet removeHttpServlet(Class websocketOrServletType) { + return ((HttpPrepareServlet) this.prepare).removeHttpServlet(websocketOrServletType); } /** @@ -179,41 +169,6 @@ public class HttpServer extends Server Service - * @param RestServlet - * @param name Service的资源名 - * @param serviceType Service的类型 - * @param service Service对象 - * @param baseServletClass RestServlet基类 - * @param prefix url前缀 - * - * @return RestServlet - */ - public T addRestServlet(String name, Class serviceType, S service, Class baseServletClass, String prefix) { - return addRestServlet(name, serviceType, service, null, baseServletClass, prefix, null); - } - - /** - * 添加RestServlet - * - * @param Service - * @param RestServlet - * @param name Service的资源名 - * @param serviceType Service的类型 - * @param service Service对象 - * @param userType 用户数据类型 - * @param baseServletClass RestServlet基类 - * @param prefix url前缀 - * - * @return RestServlet - */ - public T addRestServlet(String name, Class serviceType, S service, final Class userType, Class baseServletClass, String prefix) { - return addRestServlet(name, serviceType, service, userType, baseServletClass, prefix, null); - } - /** * 添加WebSocketServlet * @@ -236,22 +191,38 @@ public class HttpServer extends Server Service * @param HttpServlet - * @param name Service的资源名 - * @param serviceType Service的类型 * @param service Service对象 * @param userType 用户数据类型 * @param baseServletType RestServlet基类 * @param prefix url前缀 - * @param conf 配置信息 * * @return RestServlet */ - public T addRestServlet(final String name, final Class serviceType, - final S service, final Class userType, final Class baseServletType, final String prefix, final AnyValue conf) { + public T addRestServlet(final S service, final Class userType, final Class baseServletType, final String prefix) { + return addRestServlet(null, service, userType, baseServletType, prefix); + } + + /** + * 添加RestServlet + * + * @param Service + * @param HttpServlet + * @param name 资源名 + * @param service Service对象 + * @param userType 用户数据类型 + * @param baseServletType RestServlet基类 + * @param prefix url前缀 + * + * @return RestServlet + */ + public T addRestServlet(final String name, final S service, final Class userType, final Class baseServletType, final String prefix) { T servlet = null; + final boolean sncp = Sncp.isSncpDyn(service); + final String resname = name == null ? (sncp ? Sncp.getResourceName(service) : "") : name; + final Class serviceType = Sncp.getServiceType(service); for (final HttpServlet item : ((HttpPrepareServlet) this.prepare).getServlets()) { if (!(item instanceof HttpServlet)) continue; - if (item.getClass().getAnnotation(Rest.RestDynamic.class) == null) continue; + if (item.getClass().getAnnotation(Rest.RestDyn.class) == null) continue; try { Field field = item.getClass().getDeclaredField(Rest.REST_SERVICE_FIELD_NAME); if (serviceType.equals(field.getType())) { @@ -274,21 +245,21 @@ public class HttpServer extends Server EXCLUDERMETHODS = new HashSet<>(); @@ -54,7 +54,7 @@ public final class Rest { @Documented @Target({TYPE}) @Retention(RUNTIME) - public static @interface RestDynamic { + public static @interface RestDyn { } @@ -116,6 +116,32 @@ public final class Rest { return (!controller.name().isEmpty()) ? controller.name() : serviceType.getSimpleName().replaceAll("Service.*$", "").toLowerCase(); } + static boolean isRestDyn(HttpServlet servlet) { + return servlet.getClass().getAnnotation(RestDyn.class) != null; + } + + static Service getService(HttpServlet servlet) { + if (servlet == null) return null; + try { + Field ts = servlet.getClass().getDeclaredField(REST_SERVICE_FIELD_NAME); + ts.setAccessible(true); + return (Service) ts.get(servlet); + } catch (Exception e) { + return null; + } + } + + static Map getServiceMap(HttpServlet servlet) { + if (servlet == null) return null; + try { + Field ts = servlet.getClass().getDeclaredField(REST_SERVICEMAP_FIELD_NAME); + ts.setAccessible(true); + return (Map) ts.get(servlet); + } catch (Exception e) { + return null; + } + } + static T createRestWebSocketServlet(final Class webSocketType) { if (webSocketType == null) throw new RuntimeException("Rest WebSocket Class is null on createRestWebSocketServlet"); if (Modifier.isAbstract(webSocketType.getModifiers())) throw new RuntimeException("Rest WebSocket Class(" + webSocketType + ") cannot abstract on createRestWebSocketServlet"); @@ -537,8 +563,8 @@ public final class Rest { List> mappingMaps = new ArrayList<>(); cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); - { //RestDynamic - av0 = cw.visitAnnotation(Type.getDescriptor(RestDynamic.class), true); + { //RestDyn + av0 = cw.visitAnnotation(Type.getDescriptor(RestDyn.class), true); av0.visitEnd(); } { //RestDynSourceType @@ -565,7 +591,7 @@ public final class Rest { classMap.put("url", urlpath); classMap.put("moduleid", moduleid); classMap.put("repair", repair); - classMap.put("comment", comment); + //classMap.put("comment", comment); //不显示太多信息 } { //注入 @Resource private XXXService _service; @@ -1502,8 +1528,7 @@ public final class Rest { fv.visitEnd(); } - classMap.put("mappings", mappingMaps); - + //classMap.put("mappings", mappingMaps); //不显示太多信息 { //toString函数 mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null)); //mv.setDebug(true); diff --git a/src/org/redkale/net/sncp/Sncp.java b/src/org/redkale/net/sncp/Sncp.java index 6e93b09d0..72fdf7b95 100644 --- a/src/org/redkale/net/sncp/Sncp.java +++ b/src/org/redkale/net/sncp/Sncp.java @@ -89,6 +89,10 @@ public abstract class Sncp { return dyn != null && dyn.remote(); } + public static boolean isSncpDyn(Service service) { + return service.getClass().getAnnotation(SncpDyn.class) != null; + } + public static String getResourceName(Service service) { if (service == null) return null; Resource res = service.getClass().getAnnotation(Resource.class); diff --git a/src/org/redkale/net/sncp/SncpPrepareServlet.java b/src/org/redkale/net/sncp/SncpPrepareServlet.java index 8cf0aff5a..9f82a4d9b 100644 --- a/src/org/redkale/net/sncp/SncpPrepareServlet.java +++ b/src/org/redkale/net/sncp/SncpPrepareServlet.java @@ -10,6 +10,7 @@ import org.redkale.util.AnyValue; import java.io.IOException; import java.nio.ByteBuffer; import java.util.*; +import org.redkale.service.Service; import org.redkale.util.*; /** @@ -21,30 +22,35 @@ import org.redkale.util.*; */ public class SncpPrepareServlet extends PrepareServlet { + private final Object sncplock = new Object(); + private static final ByteBuffer pongBuffer = ByteBuffer.wrap("PONG".getBytes()).asReadOnlyBuffer(); @Override public void addServlet(SncpServlet servlet, Object attachment, AnyValue conf, DLong... mappings) { - addSncpServlet((SncpServlet) servlet, conf); - } - - public void addSncpServlet(SncpServlet servlet, AnyValue conf) { - setServletConf(servlet, conf); - putMapping(servlet.getServiceid(), servlet); - putServlet(servlet); - } - - public SncpServlet removeSncpServlet(String name, Class type) { - SncpServlet rs = null; - for (SncpServlet servlet : getServlets()) { - if (servlet.serviceName.equals(name) && servlet.type.equals(type)) { - rs = servlet; - break; + synchronized (sncplock) { + for (SncpServlet s : getServlets()) { + if (s.service == servlet.service) throw new RuntimeException(s.service + " repeat addSncpServlet"); } + setServletConf(servlet, conf); + putMapping(servlet.getServiceid(), servlet); + putServlet(servlet); } - if (rs != null) { - removeMapping(rs); - removeServlet(rs); + } + + public SncpServlet removeSncpServlet(Service service) { + SncpServlet rs = null; + synchronized (sncplock) { + for (SncpServlet servlet : getServlets()) { + if (servlet.service == service) { + rs = servlet; + break; + } + } + if (rs != null) { + removeMapping(rs); + removeServlet(rs); + } } return rs; } diff --git a/src/org/redkale/net/sncp/SncpServer.java b/src/org/redkale/net/sncp/SncpServer.java index 8019c2239..43098ec1c 100644 --- a/src/org/redkale/net/sncp/SncpServer.java +++ b/src/org/redkale/net/sncp/SncpServer.java @@ -73,19 +73,6 @@ public class SncpServer extends Server 泛型 - * @param resname String - * @param type Class - * - * @return SncpServlet - */ - public SncpServlet removeSncpServlet(String resname, Class type) { - return ((SncpPrepareServlet) this.prepare).removeSncpServlet(resname, type); - } - /** * 删除SncpServlet * @@ -94,20 +81,14 @@ public class SncpServer extends Server void addSncpServlet(Class serviceTypeClass, String name, T service, AnyValue conf) { - SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), name, serviceTypeClass, service); - this.prepare.addServlet(sds, null, conf); - } - + public List getSncpServlets() { return ((SncpPrepareServlet) this.prepare).getSncpServlets(); } diff --git a/test/org/redkale/test/rest/_DynHelloRestServlet1.java b/test/org/redkale/test/rest/_DynHelloRestServlet1.java index ec0210ec1..6021543d9 100644 --- a/test/org/redkale/test/rest/_DynHelloRestServlet1.java +++ b/test/org/redkale/test/rest/_DynHelloRestServlet1.java @@ -23,8 +23,8 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet { HelloService service = new HelloService(); HttpServer server = new HttpServer(); - System.out.println(server.addRestServlet("", HelloService.class, service, SimpleRestServlet.class, "/pipes")); - System.out.println(server.addRestServlet("my-res", HelloService.class, new HelloService(3), SimpleRestServlet.class, "/pipes")); + System.out.println(server.addRestServlet(service, null, SimpleRestServlet.class, "/pipes")); + System.out.println(server.addRestServlet(new HelloService(3), null, SimpleRestServlet.class, "/pipes")); DefaultAnyValue conf = DefaultAnyValue.create("port", "" + port); server.init(conf); diff --git a/test/org/redkale/test/service/ABMainService.java b/test/org/redkale/test/service/ABMainService.java index 8e21995a7..8f9f7679e 100644 --- a/test/org/redkale/test/service/ABMainService.java +++ b/test/org/redkale/test/service/ABMainService.java @@ -73,7 +73,7 @@ public class ABMainService implements Service { HttpServer server = new HttpServer(); server.getLogger().setLevel(Level.WARNING); - server.addRestServlet("", ABMainService.class, service, HttpServlet.class, "/pipes"); + server.addRestServlet(service, null, HttpServlet.class, "/pipes"); resFactory.inject(cservice); resFactory.inject(bcservice); @@ -114,7 +114,7 @@ public class ABMainService implements Service { HttpServer server = new HttpServer(); server.getLogger().setLevel(Level.WARNING); - server.addRestServlet("", ABMainService.class, service, HttpServlet.class, "/pipes"); + server.addRestServlet(service, null, HttpServlet.class, "/pipes"); server.init(DefaultAnyValue.create("port", "" + abport)); server.start();