
cc.shacocloud.mirage.restful.AbstractRequestMappingHandlerMapping Maven / Gradle / Ivy
package cc.shacocloud.mirage.restful;
import cc.shacocloud.mirage.restful.bind.annotation.RequestMapping;
import cc.shacocloud.mirage.utils.Utils;
import cc.shacocloud.mirage.utils.annotation.AnnotatedElementUtils;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 抽象的请求映射处理器映射
*/
public abstract class AbstractRequestMappingHandlerMapping extends AbstractHandlerMethodMapping {
private static final String PATH_SEPARATOR = "/";
private static final Map, RequestMappingInfo> PATH_PREFIX_MAP = new HashMap<>();
private static final RequestMappingInfo EMPTY = RequestMappingInfo.builder().paths(new String[]{""}).build();
@Nullable
@Override
protected RequestMappingInfo getMappingInfoForMethod(Method method, Class> handlerType) {
RequestMappingInfo classRequestMapping = PATH_PREFIX_MAP.computeIfAbsent(handlerType, this::getClassRequestMapping);
return createRequestMappingInfo(method, classRequestMapping);
}
/**
* 获取类级别的请求映射
*
* @param handlerType 处理器类型
* @return 路径前缀
*/
protected RequestMappingInfo getClassRequestMapping(Class> handlerType) {
RequestMappingInfo mappingInfo = createRequestMappingInfo(handlerType, EMPTY);
if (mappingInfo != null) {
String[] paths = mappingInfo.getPaths();
if (paths.length > 1) {
throw new IllegalArgumentException("类级别的 @RequestMapping 注解不支持多个路径:" + handlerType.getName());
}
return mappingInfo;
}
return EMPTY;
}
/**
* 创建请求映射信息
*/
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element, RequestMappingInfo classRequestMapping) {
RequestMapping requestMapping = AnnotatedElementUtils.getAnnotation(element, RequestMapping.class);
return requestMapping != null ? createRequestMappingInfo(requestMapping, classRequestMapping) : null;
}
/**
* 创建 {@link RequestMappingInfo} 从提供 {@link RequestMapping} 注解中
*/
protected RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping,
RequestMappingInfo classRequestMapping) {
String prefix;
if (Objects.isNull(classRequestMapping.getPaths()) || classRequestMapping.getPaths().length == 0) {
prefix = "";
} else {
prefix = classRequestMapping.getPaths()[0];
}
String[] paths = requestMapping.path();
if (Objects.isNull(paths) || paths.length == 0) {
paths = new String[]{""};
}
return RequestMappingInfo.builder()
.pathPatterns(requestMapping.patterns())
.paths(Arrays.stream(paths).map(p -> mergePath(prefix, p)).toArray(String[]::new))
.methods(requestMapping.method())
.consumes(Utils.nullOrDefault(requestMapping.consumes(), classRequestMapping::getConsumes))
.produces(Utils.nullOrDefault(requestMapping.produces(), classRequestMapping::getProduces))
.build();
}
/**
* 合并路径
*/
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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy