org.smartboot.http.restful.RestHandler Maven / Gradle / Ivy
package org.smartboot.http.restful;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.smartboot.http.common.enums.HeaderNameEnum;
import org.smartboot.http.common.enums.HeaderValueEnum;
import org.smartboot.http.restful.annotation.Controller;
import org.smartboot.http.restful.annotation.RequestMapping;
import org.smartboot.http.restful.intercept.MethodInterceptor;
import org.smartboot.http.restful.intercept.MethodInvocation;
import org.smartboot.http.restful.intercept.MethodInvocationImpl;
import org.smartboot.http.server.HttpRequest;
import org.smartboot.http.server.HttpResponse;
import org.smartboot.http.server.HttpServerHandler;
import org.smartboot.http.server.handler.HttpRouteHandler;
import org.smartboot.http.server.impl.Request;
import org.smartboot.socket.util.AttachKey;
import org.smartboot.socket.util.Attachment;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.function.BiConsumer;
/**
* @author 三刀([email protected])
* @version V1.0 , 2022/7/2
*/
class RestHandler extends HttpServerHandler {
private final HttpRouteHandler httpRouteHandler;
private AttachKey bodyBufferKey = AttachKey.valueOf("bodyBuffer");
private BiConsumer inspect = (httpRequest, response) -> {
};
private final MethodInterceptor interceptor = MethodInvocation::proceed;
public RestHandler(HttpServerHandler defaultHandler) {
this.httpRouteHandler = defaultHandler != null ? new HttpRouteHandler(defaultHandler) : new HttpRouteHandler();
}
public void addController(Object object) {
Class> clazz = object.getClass();
Controller controller = clazz.getDeclaredAnnotation(Controller.class);
String rootPath = controller.value();
System.out.println(object + "method:" + clazz.getDeclaredMethods().length);
for (Method method : clazz.getDeclaredMethods()) {
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if (requestMapping == null) {
continue;
}
String mappingUrl = getMappingUrl(rootPath, requestMapping);
httpRouteHandler.route(mappingUrl, new HttpServerHandler() {
@Override
public boolean onBodyStream(ByteBuffer buffer, Request request) {
Attachment attachment = request.getAttachment();
ByteBuffer bodyBuffer = null;
if (attachment != null) {
bodyBuffer = attachment.get(bodyBufferKey);
}
if (bodyBuffer != null || request.getContentLength() > 0 && request.getContentType().startsWith("application/json")) {
if (bodyBuffer == null) {
bodyBuffer = ByteBuffer.allocate(request.getContentLength());
if (attachment == null) {
attachment = new Attachment();
request.setAttachment(attachment);
}
attachment.put(bodyBufferKey, bodyBuffer);
}
if (buffer.remaining() <= bodyBuffer.remaining()) {
bodyBuffer.put(buffer);
} else {
int limit = buffer.limit();
buffer.limit(buffer.position() + bodyBuffer.remaining());
bodyBuffer.put(buffer);
buffer.limit(limit);
}
return !bodyBuffer.hasRemaining();
} else {
return super.onBodyStream(buffer, request);
}
}
@Override
public void handle(HttpRequest request, HttpResponse response) throws IOException {
try {
Type[] types = method.getGenericParameterTypes();
Object[] params = new Object[types.length];
Attachment attachment = request.getAttachment();
ByteBuffer bodyBuffer = null;
if (attachment != null) {
bodyBuffer = attachment.get(bodyBufferKey);
}
for (int i = 0; i < types.length; i++) {
Type type = types[i];
if (type == HttpRequest.class) {
params[i] = request;
} else if (type == HttpResponse.class) {
params[i] = response;
} else if (!type.getTypeName().startsWith("java")) {
JSONObject jsonObject;
if (bodyBuffer != null) {
jsonObject = JSON.parseObject(bodyBuffer.array());
} else {
jsonObject = new JSONObject();
request.getParameters().keySet().forEach(param -> {
jsonObject.put(param, request.getParameter(param));
});
}
params[i] = jsonObject.to(type);
} else {
System.out.println("aaaaaa......");
}
}
method.setAccessible(true);
MethodInvocation invocation = new MethodInvocationImpl(method, params, object);
inspect.accept(request, response);
Object rsp = interceptor.invoke(invocation);
// Object rsp = method.invoke(object, params);
if (rsp != null) {
byte[] bytes;
if (rsp instanceof String) {
bytes = ((String) rsp).getBytes();
} else {
response.setHeader(HeaderNameEnum.CONTENT_TYPE.getName(), HeaderValueEnum.APPLICATION_JSON.getName());
bytes = JSON.toJSONBytes(rsp);
}
//如果在controller中已经触发过write,此处的contentLength将不准,且不会生效
response.setContentLength(bytes.length);
response.write(bytes);
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
});
}
}
public void addController(Class> clazz) throws Exception {
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
if (constructor.getParameters().length != 0) {
continue;
}
constructor.setAccessible(true);
Object object = constructor.newInstance();
addController(object);
}
}
private String getMappingUrl(String rootPath, RequestMapping requestMapping) {
StringBuilder sb = new StringBuilder("/");
if (rootPath.length() > 0) {
if (rootPath.charAt(0) == '/') {
sb.append(rootPath, 1, rootPath.length());
} else {
sb.append(rootPath);
}
}
if (requestMapping.value().length() > 0) {
char sbChar = sb.charAt(sb.length() - 1);
if (requestMapping.value().charAt(0) == '/') {
if (sbChar == '/') {
sb.append(requestMapping.value(), 1, requestMapping.value().length());
} else {
sb.append(requestMapping.value());
}
} else {
if (sbChar != '/') {
sb.append('/');
}
sb.append(requestMapping.value());
}
}
return sb.toString();
}
@Override
public void onHeaderComplete(Request request) throws IOException {
httpRouteHandler.onHeaderComplete(request);
}
public void setInspect(BiConsumer inspect) {
this.inspect = inspect;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy