All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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