【问题标题】:Stream through methods to find Rest mapping information通过方法流式查找 Rest 映射信息
【发布时间】:2020-08-06 11:20:27
【问题描述】:

我有一个简单但非常难看的方法。 我遇到的问题是我觉得这可以更优雅地完成一百万倍。此外,我还想扫描一个方法以获取多个注释,而不仅仅是 Rest 端点声明。

我觉得这可以通过Annotations[] (method.getDeclaredAnnotations()) 流并由List<Annotation> restEndpointAnnotationsAndOtherAnnotations 过滤来完成,但我似乎无法让它工作。

任何帮助将不胜感激。我认为这对某些人来说可能是一个相当有趣的挑战。我遇到的主要问题(我认为)是试图将Class<? extends Annotation> 转换为Annotation,但也许我错过了标记。

public RestEndpoint mapToRestEndpoint(Method method) {

        String url = null;

        if (method.isAnnotationPresent(GetMapping.class)) {
            url = method.getAnnotation(GetMapping.class).value()[0];
        } else
        if (method.isAnnotationPresent(PutMapping.class)) {
            url = method.getAnnotation(PutMapping.class).value()[0];
        } else
        if (method.isAnnotationPresent(PostMapping.class)) {
            url = method.getAnnotation(PostMapping.class).value()[0];
        } else
        if (method.isAnnotationPresent(PatchMapping.class)) {
            url = method.getAnnotation(PatchMapping.class).value()[0];
        } else
        if (method.isAnnotationPresent(DeleteMapping.class)) {
            url = method.getAnnotation(DeleteMapping.class).value()[0];
        } else
        if (method.isAnnotationPresent(RequestMapping.class)) {
            url = method.getAnnotation(RequestMapping.class).value()[0];
        } else return null;

        return new RestEndpoint(url, true);
    }

RestEndpoint 是一个简单的 POJO

@Value
public class RestEndpoint {

    @NonNull String endpoint;
    boolean isPublic;
}

我实际上可以使用流找到它与 Rest 映射匹配的位置,但是我不能将 .value() 方法应用于它(因为它不知道它是什么注释,然后再转换为同样乏味多种注释类型)

编辑: 如果有人感兴趣,这是获取方法信息的一种非常方便的方式。

ApplicationContext context = ((ContextRefreshedEvent) event).getApplicationContext();  
context.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();

【问题讨论】:

  • 这是什么意思? Spring 内部已经拥有所有这些信息,为什么还要这样做?
  • 重点是扫描 RestController 类中的所有注解,并返回一个端点列表。我正在尝试附加一个注释,声明端点是否公开可用(请参阅stackoverflow.com/questions/61350383/…)。您的回复让我看得更远,我发现这肯定会有很大帮助 (stackoverflow.com/questions/43541080/…)

标签: java spring reflection annotations aop


【解决方案1】:

问题出在getAnnotation 中,因为它需要具体的注释类才能知道它有类似value() 的东西。您可以创建帮助方法,尝试在给定对象上调用 value() 并进行其他解析。

private String getUrl(Method method, Class<? extends Annotation> annotationClass){
    Annotation annotation = method.getAnnotation(annotationClass);
    String[] value;
    try {
        value = (String[])annotationClass.getMethod("value").invoke(annotation);
    } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
        return null;
    }
    return value[0];
}

然后像这样使用它:

String url = Stream.of(
    GetMapping.class, PutMapping.class, PostMapping.class, PatchMapping.class, DeleteMapping.class, RequestMapping.class)
    .filter(clazz -> method.isAnnotationPresent(clazz))
    .map(clazz -> getUrl(method, clazz))
    .findFirst().orElse(null);

【讨论】:

  • 是的,非常棒,谢谢 :) 查询注释上的方法很聪明!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多