
cc.shacocloud.mirage.restful.VertxRouterRequestMappingMappingRequestHandler Maven / Gradle / Ivy
package cc.shacocloud.mirage.restful;
import cc.shacocloud.mirage.restful.bind.DefaultWebDataBinderFactory;
import cc.shacocloud.mirage.restful.bind.WebBindingInitializer;
import cc.shacocloud.mirage.restful.bind.WebDataBinderFactory;
import cc.shacocloud.mirage.restful.bind.annotation.PathPatterns;
import cc.shacocloud.mirage.utils.MethodParameter;
import cc.shacocloud.mirage.utils.reflection.ParameterNameDiscoverer;
import io.vertx.core.Future;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 基于 vertx {@link Router} 的{@link RequestMappingInfo} 请求映射处理器
*
* @author 思追(shaco)
*/
public class VertxRouterRequestMappingMappingRequestHandler extends AbstractRequestMappingHandlerMapping
implements RouterMappingHandler {
// 参数名称获取器
@NotNull
protected final ParameterNameDiscoverer parameterNameDiscoverer;
// 处理器执行链映射
private final List handlerMethodMappings = new ArrayList<>(128);
// web 绑定初始化器
@Getter
@Nullable
protected WebBindingInitializer webBindingInitializer;
// 处理器方法参数解析器
@Nullable
protected HandleMethodArgumentResolverComposite argumentResolverComposite;
// 处理器方法结果值处理器
@Nullable
protected HandleMethodReturnValueHandlerComposite returnValueHandlerComposite;
// 处理拦截器
@Nullable
protected HandlerInterceptorComposite interceptorComposite;
// 处理异常解析器
@Nullable
protected HandlerExceptionResolverComposite exceptionResolverComposite;
public VertxRouterRequestMappingMappingRequestHandler(@NotNull ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
@Override
public Future bindRouterMapping(Router router) {
// 循环所有的路由映射
for (HandlerMethodMapping handlerMethodMapping : this.handlerMethodMappings) {
RequestMappingInfo mapping = handlerMethodMapping.getMapping();
HandlerExecutionChain handler = createHandlerExecutionChain(
createInvocableHandlerMethod(handlerMethodMapping.getHandlerMethod()), mapping);
bindRouterHandler(router, mapping, handler);
}
return Future.succeededFuture();
}
/**
* 绑定路由处理器
*
* @param router 路由器
* @param mapping 请求映射
* @param handler 请求响应处理器
*/
protected void bindRouterHandler(@NotNull Router router, @NotNull RequestMappingInfo mapping, @NotNull HandlerExecutionChain handler) {
for (String path : mapping.getPaths()) {
Route route = router.route().useNormalizedPath(true);
// 获取路由并且注册对应的路径匹配模式
if (PathPatterns.REGEX.equals(mapping.getPathPatterns())) {
route.pathRegex(path);
} else {
route.path(path);
}
// 注册请求方式
Arrays.stream(mapping.getMethods()).forEach(method -> route.method(HttpMethod.valueOf(method.name())));
// 注册请求类型
Arrays.stream(mapping.getConsumes()).forEach(route::consumes);
// 注册响应类型
Arrays.stream(mapping.getProduces()).forEach(route::produces);
// 设置处理器方法
route.failureHandler(handler::processException).handler(handler::handle);
}
}
@Override
protected void registerHandlerMethod(HandlerMethod handlerMethod, RequestMappingInfo mapping) {
this.handlerMethodMappings.add(new HandlerMethodMapping(handlerMethod, mapping));
}
/**
* 根据给定的{@link VertxInvokeHandler} 和 {@link RequestMappingInfo} 创建 {@link HandlerExecutionChain}
*/
protected HandlerExecutionChain createHandlerExecutionChain(VertxInvokeHandler invokeHandler,
RequestMappingInfo mapping) {
HandlerExecutionChain handlerExecutionChain = new HandlerExecutionChain(invokeHandler, mapping, this.interceptorComposite);
if (this.exceptionResolverComposite != null) {
handlerExecutionChain.setExceptionResolverComposite(exceptionResolverComposite);
}
return handlerExecutionChain;
}
/**
* 根据给定的{@link HandlerMethod}定义创建{@link VertxInvocableHandlerMethod}
*/
protected VertxInvokeHandler createInvocableHandlerMethod(@NotNull HandlerMethod handlerMethod) {
VertxInvocableHandlerMethod invocableHandlerMethod = new VertxInvocableHandlerMethod(handlerMethod);
bindInvocableHandlerMethod(invocableHandlerMethod);
return invocableHandlerMethod;
}
/**
* 绑定 {@link VertxInvocableHandlerMethod}
*/
protected void bindInvocableHandlerMethod(@NotNull VertxInvocableHandlerMethod invocableHandlerMethod) {
invocableHandlerMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
invocableHandlerMethod.setWebDataBinderFactory(createDataBinderFactory());
if (this.argumentResolverComposite != null) {
invocableHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolverComposite);
}
if (this.returnValueHandlerComposite != null) {
invocableHandlerMethod.setReturnValueHandlers(returnValueHandlerComposite);
}
}
/**
* 创建一个新的 {@link WebDataBinderFactory}实例
*
* @return 默认的 {@link DefaultWebDataBinderFactory}
*/
protected WebDataBinderFactory createDataBinderFactory() {
return new DefaultWebDataBinderFactory(webBindingInitializer);
}
@Override
protected void validateMethodMapping(@NotNull HandlerMethod handlerMethod, RequestMappingInfo mapping) {
MethodParameter returnType = handlerMethod.getReturnType();
Class> resultType = returnType.getParameterType();
if (!Future.class.isAssignableFrom(resultType)) {
throw new IllegalArgumentException(handlerMethod.getBean() + "'的方法 \n" + handlerMethod + " 返回值类型:["
+ resultType + "] 不符合预期,@RequestMapping的返回值类型必须是 'io.vertx.core.Future' 或其子类!");
}
super.validateMethodMapping(handlerMethod, mapping);
}
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class HandlerMethodMapping {
private HandlerMethod handlerMethod;
private RequestMappingInfo mapping;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy