com.kasinf.framework.rest.web.BasePathAwareHandlerMapping Maven / Gradle / Ivy
package com.kasinf.framework.rest.web;
import com.kasinf.framework.rest.config.SearchableConfiguration;
import com.kasinf.framework.rest.web.controller.SearchableController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.data.util.ProxyUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Set;
/**
* @author lkhsh
* 为所有@SearchableController加上 basePath
*/
@Slf4j
public class BasePathAwareHandlerMapping extends RequestMappingHandlerMapping {
private final SearchableConfiguration configuration;
private String prefix;
public BasePathAwareHandlerMapping(SearchableConfiguration configuration) {
this.configuration = configuration;
}
/**
* 只有@SearchableController注解的才执行
*
* @param beanType 默认类型
* @return 是否过滤
*/
@Override
protected boolean isHandler(Class> beanType) {
return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, SearchableController.class);
}
/**
* 在初始化之后执行,给prefix赋值
*/
@Override
public void afterPropertiesSet() {
URI baseUri = configuration.getBaseUri();
prefix = baseUri.toString();
super.afterPropertiesSet();
}
/**
* 获取方法的请求路径
*
* @param method 方法
* @param handlerType 类型
* @return 路径
*/
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class> handlerType) {
RequestMappingInfo info = super.getMappingForMethod(method, handlerType);
if (info == null) {
return null;
}
if (AnnotatedElementUtils.hasAnnotation(handlerType, SearchableController.class)) {
PatternsRequestCondition patternsCondition = customize(info.getPatternsCondition(), prefix);
RequestMappingInfo requestMappingInfo = new RequestMappingInfo(patternsCondition, info.getMethodsCondition(), info.getParamsCondition(),
info.getHeadersCondition(), info.getConsumesCondition(), info.getProducesCondition(), info.getCustomCondition());
log.info("change {} onto {};", info, requestMappingInfo);
return requestMappingInfo;
}
log.info("Request Mapping: {}",info);
return info;
}
/**
* Customize the given {@link PatternsRequestCondition} and prefix.
*
* @param condition will never be {@literal null}.
* @param prefix will never be {@literal null}.
* @return {@link PatternsRequestCondition}
*/
protected PatternsRequestCondition customize(PatternsRequestCondition condition, String prefix) {
Set patterns = condition.getPatterns();
String[] augmentedPatterns = new String[patterns.size()];
int count = 0;
for (String pattern : patterns) {
augmentedPatterns[count++] = prefix.concat(pattern);
}
return new PatternsRequestCondition(augmentedPatterns, getUrlPathHelper(), getPathMatcher(),
useSuffixPatternMatch(), useTrailingSlashMatch(), getFileExtensions());
}
}