cc.shacocloud.mirage.web.AbstractRequestMappingHandlerMapping Maven / Gradle / Ivy
package cc.shacocloud.mirage.web;
import cc.shacocloud.mirage.web.bind.annotation.RequestMapping;
import io.vertx.core.http.HttpMethod;
import org.jetbrains.annotations.Nullable;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* 抽象的请求映射处理器映射
*/
public abstract class AbstractRequestMappingHandlerMapping extends AbstractHandlerMethodMapping {
private static final String PATH_SEPARATOR = "/";
private static final Map, String> PATH_PREFIX_MAP = new HashMap<>();
@Override
protected boolean isHandler(Class> beanType) {
return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
}
@Override
protected RequestMappingInfo getMappingInfoForMethod(Method method, Class> handlerType) {
String prefix = PATH_PREFIX_MAP.computeIfAbsent(handlerType, this::getPathPrefix);
return createRequestMappingInfo(method, prefix);
}
/**
* 合并路径
*/
private String mergePath(String prefix, String path) {
if (prefix == null || prefix.isEmpty())
return path.startsWith(PATH_SEPARATOR) ? path : PATH_SEPARATOR + path;
prefix = prefix.startsWith(PATH_SEPARATOR) ? prefix : PATH_SEPARATOR + prefix;
if (path.equals("")) return prefix;
boolean p1 = prefix.endsWith(PATH_SEPARATOR);
boolean p2 = path.startsWith(PATH_SEPARATOR);
if (p1 && p2) {
path = path.substring(PATH_SEPARATOR.length());
} else if (!p1 && !p2) {
path = PATH_SEPARATOR + path;
}
return prefix + path;
}
/**
* 获取处理器下路径前缀
*
* @param handlerType 处理器类型
* @return 路径前缀
*/
protected String getPathPrefix(Class> handlerType) {
RequestMappingInfo mappingInfo = createRequestMappingInfo(handlerType, null);
if (mappingInfo != null) {
String[] paths = mappingInfo.getPaths();
Assert.isTrue(!(paths.length > 1), () -> "处理程序级别的 @RequestMapping 注解不支持多个路径:" + handlerType.getName());
return paths[0];
}
return "";
}
/**
* 创建请求映射信息
*/
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element, String prefix) {
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
return requestMapping != null ? createRequestMappingInfo(requestMapping, prefix) : null;
}
/**
* 创建 {@link RequestMappingInfo} 从提供 {@link RequestMapping} 注解中
*/
protected RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping, String prefix) {
String[] paths = requestMapping.path();
if (paths.length == 0) {
paths = new String[]{""};
}
return RequestMappingInfo.builder()
.paths(Arrays.stream(paths).map(p -> mergePath(prefix, p)).toArray(String[]::new))
.methods(Arrays.stream(requestMapping.method()).map(m -> HttpMethod.valueOf(m.name())).toArray(HttpMethod[]::new))
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy