
cc.shacocloud.mirage.web.VertxInvocableHandlerMethod Maven / Gradle / Ivy
package cc.shacocloud.mirage.web;
import cc.shacocloud.mirage.web.bind.WebDataBinderFactory;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import lombok.Setter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.log.LogFormatUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.Assert;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 扩展了{@link InvocableHandlerMethod},使其能够通过已注册的{@link HandleMethodReturnValueHandler}处理返回值。
*/
public class VertxInvocableHandlerMethod extends InvocableHandlerMethod implements VertxInvokeHandler {
private static final Log logger = LogFactory.getLog(VertxInvocableHandlerMethod.class);
@Setter
@Nullable
private HandleMethodReturnValueHandlerComposite returnValueHandlers;
@Setter
@Nullable
private WebDataBinderFactory webDataBinderFactory;
public VertxInvocableHandlerMethod(Object handler, Method method) {
super(handler, method);
}
public VertxInvocableHandlerMethod(HandlerMethod handlerMethod) {
super(handlerMethod);
}
/**
* 调用方法并通过配置的{@link HandleMethodReturnValueHandlerComposite}来处理返回值。
*/
@Override
public Future invokeAndHandleRoutingContext(RoutingContext routingContext, Object... providedArgs) {
return invokeAndHandleHandlerMethod(routingContext, createWithResolvedBean(), providedArgs);
}
@Override
public Future invokeAndHandleHandlerMethod(RoutingContext routingContext,
HandlerMethod handlerMethod,
Object... providedArgs) {
Assert.state(this.returnValueHandlers != null, "未设置结果值处理器!");
HttpRequest request = routingContext.request();
HttpResponse response = routingContext.response();
// 合并参数
Object[] mergeProvidedArgs = Arrays.copyOf(providedArgs, providedArgs.length + 3);
System.arraycopy(new Object[]{routingContext, request, response}, 0, mergeProvidedArgs, providedArgs.length, 3);
Future> returnValue;
try {
// 执行请求
InvocableHandlerMethod invocableHandlerMethod = createInvocableHandlerMethodAndCopyProperty(handlerMethod);
returnValue = invocableHandlerMethod.invokeForRequest(request, webDataBinderFactory, mergeProvidedArgs);
} catch (Exception e) {
return Future.failedFuture(e);
}
// 处理结果
return returnValue.compose(value -> resultHandle(value, handlerMethod, response));
}
@Override
public Future resultHandle(Object result, HttpResponse response) {
return resultHandle(result, createWithResolvedBean(), response);
}
@Override
public Future resultHandle(Object result,
HandlerMethod handlerMethod,
HttpResponse response) {
Assert.state(this.returnValueHandlers != null, "未设置结果值处理器!");
if (result != null && !Void.TYPE.equals(result.getClass())) {
if (logger.isDebugEnabled()) {
logger.debug("解析处理器方法 [" + handlerMethod + "] 的执行结果 : [" + LogFormatUtils.formatValue(result, false) + "]");
}
try {
// 处理返回结果
MethodParameter returnValueType = handlerMethod.getReturnValueType(result);
return this.returnValueHandlers.handleReturnValue(response, returnValueType, result);
} catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug(formatErrorForReturnValue(result), ex);
}
return Future.failedFuture(ex);
}
}
return Future.succeededFuture();
}
@Override
public Object getHandler() {
return createWithResolvedBean();
}
private String formatErrorForReturnValue(@Nullable Object returnValue) {
return "处理返回值=[" + returnValue + "]时出错" +
(returnValue != null ? ", 类型=" + returnValue.getClass().getName() : "") + " 为 " + toString();
}
protected InvocableHandlerMethod createInvocableHandlerMethodAndCopyProperty(HandlerMethod handlerMethod) {
if (handlerMethod == this) return this;
InvocableHandlerMethod invocableHandlerMethod = handlerMethod instanceof InvocableHandlerMethod
? (InvocableHandlerMethod) handlerMethod
: new InvocableHandlerMethod(handlerMethod);
invocableHandlerMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
invocableHandlerMethod.setHandlerMethodArgumentResolvers(this.resolvers);
return invocableHandlerMethod;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy