HttpSimpleRequest 增加 rpc 功能

This commit is contained in:
Redkale
2020-06-21 08:57:59 +08:00
parent 44ed3259f9
commit 807fe63cbe
8 changed files with 79 additions and 12 deletions

View File

@@ -36,10 +36,11 @@ public class HttpSimpleRequestCoder implements MessageCoder<HttpSimpleRequest> {
byte[] headers = MessageCoder.getBytes(data.getHeaders()); byte[] headers = MessageCoder.getBytes(data.getHeaders());
byte[] params = MessageCoder.getBytes(data.getParams()); byte[] params = MessageCoder.getBytes(data.getParams());
byte[] body = MessageCoder.getBytes(data.getBody()); byte[] body = MessageCoder.getBytes(data.getBody());
int count = 4 + requestURI.length + 2 + remoteAddr.length + 2 + sessionid.length int count = 1 + 4 + requestURI.length + 2 + remoteAddr.length + 2 + sessionid.length
+ 2 + contentType.length + headers.length + params.length + 4 + body.length; + 2 + contentType.length + headers.length + params.length + 4 + body.length;
byte[] bs = new byte[count]; byte[] bs = new byte[count];
ByteBuffer buffer = ByteBuffer.wrap(bs); ByteBuffer buffer = ByteBuffer.wrap(bs);
buffer.put((byte) (data.isRpc() ? 'T' : 'F'));
buffer.putInt(requestURI.length); buffer.putInt(requestURI.length);
if (requestURI.length > 0) buffer.put(requestURI); if (requestURI.length > 0) buffer.put(requestURI);
buffer.putChar((char) remoteAddr.length); buffer.putChar((char) remoteAddr.length);
@@ -60,6 +61,7 @@ public class HttpSimpleRequestCoder implements MessageCoder<HttpSimpleRequest> {
if (data == null) return null; if (data == null) return null;
ByteBuffer buffer = ByteBuffer.wrap(data); ByteBuffer buffer = ByteBuffer.wrap(data);
HttpSimpleRequest req = new HttpSimpleRequest(); HttpSimpleRequest req = new HttpSimpleRequest();
req.setRpc(buffer.get() == 'T');
req.setRequestURI(MessageCoder.getLongString(buffer)); req.setRequestURI(MessageCoder.getLongString(buffer));
req.setRemoteAddr(MessageCoder.getShortString(buffer)); req.setRemoteAddr(MessageCoder.getShortString(buffer));
req.setSessionid(MessageCoder.getShortString(buffer)); req.setSessionid(MessageCoder.getShortString(buffer));

View File

@@ -30,6 +30,11 @@ public @interface HttpMapping {
*/ */
int actionid() default 0; int actionid() default 0;
/**
* 请求地址
*
* @return String
*/
String url(); String url();
/** /**
@@ -41,6 +46,13 @@ public @interface HttpMapping {
*/ */
int cacheseconds() default 0; int cacheseconds() default 0;
/**
* 是否只接受RPC请求 默认为false
*
* @return 默认false
*/
boolean rpconly() default false;
/** /**
* 是否鉴权,默认需要鉴权 <br> * 是否鉴权,默认需要鉴权 <br>
* *

View File

@@ -36,6 +36,8 @@ public class HttpRequest extends Request<HttpContext> {
public static final String SESSIONID_NAME = "JSESSIONID"; public static final String SESSIONID_NAME = "JSESSIONID";
protected boolean rpc;
@Comment("Method GET/POST/...") @Comment("Method GET/POST/...")
protected String method; protected String method;
@@ -97,6 +99,7 @@ public class HttpRequest extends Request<HttpContext> {
super(context, null); super(context, null);
this.remoteAddrHeader = null; this.remoteAddrHeader = null;
if (req != null) { if (req != null) {
this.rpc = req.rpc;
if (req.getBody() != null) this.array.write(req.getBody()); if (req.getBody() != null) this.array.write(req.getBody());
if (req.getHeaders() != null) this.headers.putAll(req.getHeaders()); if (req.getHeaders() != null) this.headers.putAll(req.getHeaders());
if (req.getParams() != null) this.params.putAll(req.getParams()); if (req.getParams() != null) this.params.putAll(req.getParams());
@@ -122,6 +125,7 @@ public class HttpRequest extends Request<HttpContext> {
} }
req.setRequestURI(uri); req.setRequestURI(uri);
req.setSessionid(getSessionid(false)); req.setSessionid(getSessionid(false));
req.setRpc(this.rpc);
return req; return req;
} }

View File

@@ -44,6 +44,10 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
@Override @Override
public void execute(HttpRequest request, HttpResponse response) throws IOException { public void execute(HttpRequest request, HttpResponse response) throws IOException {
InnerActionEntry entry = (InnerActionEntry) request.attachment; InnerActionEntry entry = (InnerActionEntry) request.attachment;
if (entry.rpconly && !request.rpc) {
response.finish(503, null);
return;
}
if (entry.cacheseconds > 0) {//有缓存设置 if (entry.cacheseconds > 0) {//有缓存设置
CacheEntry ce = entry.cache.get(request.getRequestURI()); CacheEntry ce = entry.cache.get(request.getRequestURI());
if (ce != null && ce.time + entry.cacheseconds > System.currentTimeMillis()) { //缓存有效 if (ce != null && ce.time + entry.cacheseconds > System.currentTimeMillis()) { //缓存有效
@@ -216,18 +220,19 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
protected static final class InnerActionEntry { protected static final class InnerActionEntry {
InnerActionEntry(int moduleid, int actionid, String name, String[] methods, Method method, HttpServlet servlet) { InnerActionEntry(int moduleid, int actionid, String name, String[] methods, Method method, HttpServlet servlet) {
this(moduleid, actionid, name, methods, method, auth(method), cacheseconds(method), servlet); this(moduleid, actionid, name, methods, method, rpconly(method), auth(method), cacheseconds(method), servlet);
this.annotations = annotations(method); this.annotations = annotations(method);
} }
//供Rest类使用参数不能随便更改 //供Rest类使用参数不能随便更改
public InnerActionEntry(int moduleid, int actionid, String name, String[] methods, Method method, boolean auth, int cacheseconds, HttpServlet servlet) { public InnerActionEntry(int moduleid, int actionid, String name, String[] methods, Method method, boolean rpconly, boolean auth, int cacheseconds, HttpServlet servlet) {
this.moduleid = moduleid; this.moduleid = moduleid;
this.actionid = actionid; this.actionid = actionid;
this.name = name; this.name = name;
this.methods = methods; this.methods = methods;
this.method = method; //rest构建会为null this.method = method; //rest构建会为null
this.servlet = servlet; this.servlet = servlet;
this.rpconly = rpconly;
this.auth = auth; this.auth = auth;
this.cacheseconds = cacheseconds; this.cacheseconds = cacheseconds;
this.cache = cacheseconds > 0 ? new ConcurrentHashMap<>() : null; this.cache = cacheseconds > 0 ? new ConcurrentHashMap<>() : null;
@@ -245,6 +250,11 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
return mapping == null || mapping.auth(); return mapping == null || mapping.auth();
} }
protected static boolean rpconly(Method method) {
HttpMapping mapping = method.getAnnotation(HttpMapping.class);
return mapping == null || mapping.rpconly();
}
protected static int cacheseconds(Method method) { protected static int cacheseconds(Method method) {
HttpMapping mapping = method.getAnnotation(HttpMapping.class); HttpMapping mapping = method.getAnnotation(HttpMapping.class);
return mapping == null ? 0 : mapping.cacheseconds(); return mapping == null ? 0 : mapping.cacheseconds();
@@ -273,6 +283,8 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
final int cacheseconds; final int cacheseconds;
final boolean rpconly;
final boolean auth; final boolean auth;
final int moduleid; final int moduleid;

View File

@@ -23,30 +23,34 @@ import org.redkale.util.*;
public class HttpSimpleRequest implements java.io.Serializable { public class HttpSimpleRequest implements java.io.Serializable {
@ConvertColumn(index = 1) @ConvertColumn(index = 1)
@Comment("是否RPC请求, 该类通常是为RPC创建的故默认是true")
protected boolean rpc = true;
@ConvertColumn(index = 2)
@Comment("请求的URI") @Comment("请求的URI")
protected String requestURI; protected String requestURI;
@ConvertColumn(index = 2) @ConvertColumn(index = 3)
@Comment("客户端IP") @Comment("客户端IP")
protected String remoteAddr; protected String remoteAddr;
@ConvertColumn(index = 3) @ConvertColumn(index = 4)
@Comment("会话ID") @Comment("会话ID")
protected String sessionid; protected String sessionid;
@ConvertColumn(index = 4) @ConvertColumn(index = 5)
@Comment("Content-Type") @Comment("Content-Type")
protected String contentType; protected String contentType;
@ConvertColumn(index = 5) @ConvertColumn(index = 6)
@Comment("http header信息") @Comment("http header信息")
protected Map<String, String> headers; protected Map<String, String> headers;
@ConvertColumn(index = 6) @ConvertColumn(index = 7)
@Comment("参数信息") @Comment("参数信息")
protected Map<String, String> params; protected Map<String, String> params;
@ConvertColumn(index = 7) @ConvertColumn(index = 8)
@Comment("http body信息") @Comment("http body信息")
protected byte[] body; //对应HttpRequest.array protected byte[] body; //对应HttpRequest.array
@@ -63,6 +67,11 @@ public class HttpSimpleRequest implements java.io.Serializable {
return req; return req;
} }
public HttpSimpleRequest rpc(boolean rpc) {
this.rpc = rpc;
return this;
}
public HttpSimpleRequest requestURI(String requestURI) { public HttpSimpleRequest requestURI(String requestURI) {
this.requestURI = requestURI; this.requestURI = requestURI;
return this; return this;
@@ -175,6 +184,14 @@ public class HttpSimpleRequest implements java.io.Serializable {
return this; return this;
} }
public boolean isRpc() {
return rpc;
}
public void setRpc(boolean rpc) {
this.rpc = rpc;
}
public String getRequestURI() { public String getRequestURI() {
return requestURI; return requestURI;
} }

View File

@@ -781,6 +781,7 @@ public final class Rest {
final String supDynName = baseServletType.getName().replace('.', '/'); final String supDynName = baseServletType.getName().replace('.', '/');
final RestService controller = serviceType.getAnnotation(RestService.class); final RestService controller = serviceType.getAnnotation(RestService.class);
if (controller != null && controller.ignore()) throw new RuntimeException(serviceType + " is ignore Rest Service Class"); //标记为ignore=true不创建Servlet if (controller != null && controller.ignore()) throw new RuntimeException(serviceType + " is ignore Rest Service Class"); //标记为ignore=true不创建Servlet
final boolean serrpconly = controller != null && controller.rpconly();
ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader; ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
String stname = serviceType.getSimpleName(); String stname = serviceType.getSimpleName();
if (stname.startsWith("Service")) { //类似ServiceWatchService这样的类保留第一个Service字样 if (stname.startsWith("Service")) { //类似ServiceWatchService这样的类保留第一个Service字样
@@ -858,12 +859,12 @@ public final class Rest {
} }
paramtypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType)); paramtypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType));
if (mappings.length == 0) { //没有Mapping设置一个默认值 if (mappings.length == 0) { //没有Mapping设置一个默认值
MappingEntry entry = new MappingEntry(methodidex, null, bigmodulename, method); MappingEntry entry = new MappingEntry(serrpconly, methodidex, null, bigmodulename, method);
if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat"); if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
entrys.add(entry); entrys.add(entry);
} else { } else {
for (RestMapping mapping : mappings) { for (RestMapping mapping : mappings) {
MappingEntry entry = new MappingEntry(methodidex, mapping, defmodulename, method); MappingEntry entry = new MappingEntry(serrpconly, methodidex, mapping, defmodulename, method);
if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat"); if (entrys.contains(entry)) throw new RuntimeException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
entrys.add(entry); entrys.add(entry);
} }
@@ -1169,6 +1170,7 @@ public final class Rest {
av0 = mv.visitAnnotation(mappingDesc, true); av0 = mv.visitAnnotation(mappingDesc, true);
String url = (catalog.isEmpty() ? "/" : ("/" + catalog + "/")) + (defmodulename.isEmpty() ? "" : (defmodulename + "/")) + entry.name + (reqpath ? "/" : ""); String url = (catalog.isEmpty() ? "/" : ("/" + catalog + "/")) + (defmodulename.isEmpty() ? "" : (defmodulename + "/")) + entry.name + (reqpath ? "/" : "");
av0.visit("url", url); av0.visit("url", url);
av0.visit("rpconly", entry.rpconly);
av0.visit("auth", entry.auth); av0.visit("auth", entry.auth);
av0.visit("cacheseconds", entry.cacheseconds); av0.visit("cacheseconds", entry.cacheseconds);
av0.visit("actionid", entry.actionid); av0.visit("actionid", entry.actionid);
@@ -1185,6 +1187,7 @@ public final class Rest {
av0.visitEnd(); av0.visitEnd();
mappingMap.put("url", url); mappingMap.put("url", url);
mappingMap.put("rpconly", entry.rpconly);
mappingMap.put("auth", entry.auth); mappingMap.put("auth", entry.auth);
mappingMap.put("cacheseconds", entry.cacheseconds); mappingMap.put("cacheseconds", entry.cacheseconds);
mappingMap.put("actionid", entry.actionid); mappingMap.put("actionid", entry.actionid);
@@ -2134,7 +2137,7 @@ public final class Rest {
} }
} }
public MappingEntry(int methodidx, RestMapping mapping, final String defmodulename, Method method) { public MappingEntry(final boolean serrpconly, int methodidx, RestMapping mapping, final String defmodulename, Method method) {
if (mapping == null) mapping = DEFAULT__MAPPING; if (mapping == null) mapping = DEFAULT__MAPPING;
this.methodidx = methodidx; this.methodidx = methodidx;
this.ignore = mapping.ignore(); this.ignore = mapping.ignore();
@@ -2148,6 +2151,7 @@ public final class Rest {
this.mappingMethod = method; this.mappingMethod = method;
this.methods = mapping.methods(); this.methods = mapping.methods();
this.auth = mapping.auth(); this.auth = mapping.auth();
this.rpconly = serrpconly || mapping.rpconly();
this.actionid = mapping.actionid(); this.actionid = mapping.actionid();
this.cacheseconds = mapping.cacheseconds(); this.cacheseconds = mapping.cacheseconds();
this.comment = mapping.comment(); this.comment = mapping.comment();
@@ -2181,6 +2185,8 @@ public final class Rest {
public final String[] methods; public final String[] methods;
public final boolean rpconly;
public final boolean auth; public final boolean auth;
public final int actionid; public final int actionid;

View File

@@ -46,6 +46,13 @@ public @interface RestMapping {
*/ */
String comment() default ""; String comment() default "";
/**
* 是否只接收RPC请求, 对应&#64;HttpMapping.rpconly
*
* @return boolean
*/
boolean rpconly() default true;
/** /**
* 是否鉴权,默认需要鉴权, 对应&#64;HttpMapping.auth * 是否鉴权,默认需要鉴权, 对应&#64;HttpMapping.auth
* *

View File

@@ -43,6 +43,13 @@ public @interface RestService {
*/ */
int moduleid() default 0; int moduleid() default 0;
/**
* 是否只接受RPC请求 默认为false, 为true则覆盖所有&#64;RestMapping的方法的rpconly值都转为true
*
* @return 默认false
*/
boolean rpconly() default false;
/** /**
* 没有标记&#64;RestMapping的方法是否转换 默认为false * 没有标记&#64;RestMapping的方法是否转换 默认为false
* *