package com.backendsys.modules.common.config.security; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.backendsys.modules.common.config.security.annotations.Anonymous; import org.apache.commons.lang3.RegExUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import cn.hutool.core.util.ReUtil; @Configuration public class AnonymousProperties implements InitializingBean, ApplicationContextAware { private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); private ApplicationContext applicationContext; private List urls = new ArrayList<>(); public String ASTERISK = "*"; @Override public void afterPropertiesSet() throws Exception { // System.out.println("afterPropertiesSet:"); // 将整个项目所有的bean对象都拿出来 RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); // 获取每一个方法,获取url和类与方法对应的信息 Map map = mapping.getHandlerMethods(); // info代表每一个url对象 map.keySet().forEach(info -> { // 获取类和方法 HandlerMethod handlerMethod = map.get(info); // 获取方法上边的注解 替代path variable 为 * // AnnotationUtils.findAnnotation()为第三方的依赖,进行判断 一个方法上有没有注解 Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); if (method != null) { // Pattern pattern = Pattern.compile("\\{(\\w+) \\[(.+?)\\]}"); // // 排除 SSE协议接口 多余的字段 // String infoContent = info.toString().replace(", produces [text/event-stream]", ""); // Matcher matcher = pattern.matcher(infoContent); //// System.out.println("matcher1:"); //// System.out.println(matcher); //// Matcher matcher = pattern.matcher(info.toString()); // if (matcher.find()) { // String url = matcher.group(2); // System.out.println("url: " + url); // urls.add(url); // } // 正则表达式,匹配第一个方括号内的内容 Pattern regex = Pattern.compile("\\[(.*?)\\]"); String url = ReUtil.getGroup1(regex, info.toString()); if (StrUtil.isNotEmpty(url)) { // System.out.println("(@Anonymous) url: " + url); urls.add(url); } } //// ifPresent()方法就是会返回一个boolean类型值,如果对象不为空则为真,如果为空则为false // Optional.ofNullable(method).ifPresent(anonymous -> // //获取url的Set集合,一个方法可能对应多个url // info.getPatternsCondition().getPatterns() // .forEach( // url -> urls.add(RegExUtils.replaceAll(String.valueOf(url), PATTERN, ASTERISK)) // )); // 获取类上边的注解, 替代path variable 为 * Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns() .forEach(url -> urls.add(RegExUtils.replaceAll(String.valueOf(url), PATTERN, ASTERISK)))); }); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public List getUrlsList() { return urls; } public String[] getUrls() { return Convert.toStrArray(urls); } public void setUrls(List urls) { this.urls = urls; } }