This commit is contained in:
Redkale
2017-05-30 11:12:42 +08:00
parent 14238a0203
commit 0aed26652d
10 changed files with 140 additions and 138 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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<String, HttpContext, Http
return servlet;
}
public <T extends HttpServlet> List<HttpServlet> removeHttpServlet(final Class<T> servletOrServiceOrWsType) {
public <T extends HttpServlet> HttpServlet removeHttpServlet(Service service) {
Predicate<MappingEntry> 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<String, Service> 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<String, Service> 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<Map.Entry<String, WebSocketServlet>> predicateFilter = null;
List<HttpServlet> list = removeHttpServlet(predicateEntry, predicateFilter);
return list == null || list.isEmpty() ? null : list.get(0);
}
public <T extends WebSocket> HttpServlet removeHttpServlet(Class<T> websocketOrServletType) {
Predicate<MappingEntry> 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<Map.Entry<String, WebSocketServlet>> 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<HttpServlet> 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<MappingEntry> predicateEntry = (t) -> t.mapping.equals(mapping);
Predicate<Map.Entry<String, WebSocketServlet>> predicateFilter = (t) -> t.getKey().equals(mapping);
return removeHttpServlet(predicateEntry, predicateFilter);
List<HttpServlet> list = removeHttpServlet(predicateEntry, predicateFilter);
return list == null || list.isEmpty() ? null : list.get(0);
}
public boolean addForbidURIReg(final String urlreg) {

View File

@@ -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<String, HttpContext, HttpRequest, HttpRes
/**
* 删除HttpServlet
*
* @param servlet HttpServlet
* @param service Service
*
* @return HttpServlet
*/
public HttpServlet removeHttpServlet(HttpServlet servlet) {
return ((HttpPrepareServlet) this.prepare).removeHttpServlet(servlet);
public HttpServlet removeHttpServlet(Service service) {
return ((HttpPrepareServlet) this.prepare).removeHttpServlet(service);
}
/**
* 删除HttpServlet
*
* @param servletOrServiceOrWsType Class
* @param websocketOrServletType Class
*
* @return HttpServlet
*/
public List<HttpServlet> removeHttpServlet(Class servletOrServiceOrWsType) {
return ((HttpPrepareServlet) this.prepare).removeHttpServlet(servletOrServiceOrWsType);
}
/**
* 删除HttpServlet
*
* @param mapping String
*
* @return HttpServlet
*/
public List<HttpServlet> removeHttpServlet(String mapping) {
return ((HttpPrepareServlet) this.prepare).removeHttpServlet(mapping);
public <T extends WebSocket> HttpServlet removeHttpServlet(Class<T> websocketOrServletType) {
return ((HttpPrepareServlet) this.prepare).removeHttpServlet(websocketOrServletType);
}
/**
@@ -179,41 +169,6 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
return this;
}
/**
* 添加RestServlet
*
* @param <S> Service
* @param <T> RestServlet
* @param name Service的资源名
* @param serviceType Service的类型
* @param service Service对象
* @param baseServletClass RestServlet基类
* @param prefix url前缀
*
* @return RestServlet
*/
public <S extends Service, T extends HttpServlet> T addRestServlet(String name, Class<S> serviceType, S service, Class<T> baseServletClass, String prefix) {
return addRestServlet(name, serviceType, service, null, baseServletClass, prefix, null);
}
/**
* 添加RestServlet
*
* @param <S> Service
* @param <T> RestServlet
* @param name Service的资源名
* @param serviceType Service的类型
* @param service Service对象
* @param userType 用户数据类型
* @param baseServletClass RestServlet基类
* @param prefix url前缀
*
* @return RestServlet
*/
public <S extends Service, T extends HttpServlet> T addRestServlet(String name, Class<S> serviceType, S service, final Class userType, Class<T> baseServletClass, String prefix) {
return addRestServlet(name, serviceType, service, userType, baseServletClass, prefix, null);
}
/**
* 添加WebSocketServlet
*
@@ -236,22 +191,38 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
*
* @param <S> Service
* @param <T> HttpServlet
* @param name Service的资源名
* @param serviceType Service的类型
* @param service Service对象
* @param userType 用户数据类型
* @param baseServletType RestServlet基类
* @param prefix url前缀
* @param conf 配置信息
*
* @return RestServlet
*/
public <S extends Service, T extends HttpServlet> T addRestServlet(final String name, final Class<S> serviceType,
final S service, final Class userType, final Class<T> baseServletType, final String prefix, final AnyValue conf) {
public <S extends Service, T extends HttpServlet> T addRestServlet(final S service, final Class userType, final Class<T> baseServletType, final String prefix) {
return addRestServlet(null, service, userType, baseServletType, prefix);
}
/**
* 添加RestServlet
*
* @param <S> Service
* @param <T> HttpServlet
* @param name 资源名
* @param service Service对象
* @param userType 用户数据类型
* @param baseServletType RestServlet基类
* @param prefix url前缀
*
* @return RestServlet
*/
public <S extends Service, T extends HttpServlet> T addRestServlet(final String name, final S service, final Class userType, final Class<T> 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<S> 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<String, HttpContext, HttpRequest, HttpRes
mapfield.setAccessible(true);
Service firstService = (Service) field.get(servlet);
if (name.isEmpty()) {
if (resname.isEmpty()) {
field.set(servlet, service);
firstService = service;
}
Map map = (Map) mapfield.get(servlet);
if (map == null && !name.isEmpty()) map = new HashMap();
if (map == null && !resname.isEmpty()) map = new HashMap();
if (map != null) {
map.put(name, service);
map.put(resname, service);
if (firstService != null) map.put("", firstService);
}
mapfield.set(servlet, map);
} catch (Exception e) {
throw new RuntimeException(serviceType + " generate rest servlet error", e);
}
if (first) this.prepare.addServlet(servlet, prefix, conf);
if (first) this.prepare.addServlet(servlet, prefix, sncp ? Sncp.getConf(service) : null);
return servlet;
}

View File

@@ -33,11 +33,11 @@ public final class Rest {
public static final String REST_HEADER_RESOURCE_NAME = "rest-resource-name";
static final String REST_SERVICE_FIELD_NAME = "_service";
static final String REST_SERVICE_FIELD_NAME = "_redkale_service";
static final String REST_SERVICEMAP_FIELD_NAME = "_servicemap"; //如果只有name=""的Service资源则实例中_servicemap必须为null
static final String REST_SERVICEMAP_FIELD_NAME = "_redkale_servicemap"; //如果只有name=""的Service资源则实例中_servicemap必须为null
private static final String REST_PARAMTYPES_FIELD_NAME = "_paramtypes"; //存在泛型的参数数组 Type[][] 第1维度是方法的下标 第二维度是参数的下标
private static final String REST_PARAMTYPES_FIELD_NAME = "_redkale_paramtypes"; //存在泛型的参数数组 Type[][] 第1维度是方法的下标 第二维度是参数的下标
private static final Set<String> 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<String, Service> 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 extends HttpServlet> T createRestWebSocketServlet(final Class<? extends WebSocket> 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<Map<String, Object>> 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);

View File

@@ -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);

View File

@@ -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<DLong, SncpContext, SncpRequest, SncpResponse, SncpServlet> {
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 <T> SncpServlet removeSncpServlet(String name, Class<T> 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 <T> 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;
}

View File

@@ -73,19 +73,6 @@ public class SncpServer extends Server<DLong, SncpContext, SncpRequest, SncpResp
return this;
}
/**
* 删除SncpServlet
*
* @param <T> 泛型
* @param resname String
* @param type Class
*
* @return SncpServlet
*/
public <T extends Service> SncpServlet removeSncpServlet(String resname, Class<T> type) {
return ((SncpPrepareServlet) this.prepare).removeSncpServlet(resname, type);
}
/**
* 删除SncpServlet
*
@@ -94,20 +81,14 @@ public class SncpServer extends Server<DLong, SncpContext, SncpRequest, SncpResp
* @return SncpServlet
*/
public SncpServlet removeSncpServlet(Service sncpService) {
String resname = Sncp.getResourceName(sncpService);
return ((SncpPrepareServlet) this.prepare).removeSncpServlet(resname, Sncp.getResourceType(sncpService));
return ((SncpPrepareServlet) this.prepare).removeSncpServlet(sncpService);
}
public void addSncpServlet(Service sncpService) {
SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), Sncp.getResourceName(sncpService), Sncp.getResourceType(sncpService), sncpService);
this.prepare.addServlet(sds, null, Sncp.getConf(sncpService));
}
public <T extends Service> void addSncpServlet(Class<T> 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<SncpServlet> getSncpServlets() {
return ((SncpPrepareServlet) this.prepare).getSncpServlets();
}

View File

@@ -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);

View File

@@ -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();