通过方法流式查找 Rest 映射信息
Stream through methods to find Rest mapping information
我有一个简单但非常难看的方法。
我遇到的问题是我觉得这可以优雅地完成一百万倍。此外,我还想为多个注释扫描一个方法,而不仅仅是 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();
问题出在 getAnnotation
,因为它需要具体注释 class 才能知道它有类似 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);
我有一个简单但非常难看的方法。 我遇到的问题是我觉得这可以优雅地完成一百万倍。此外,我还想为多个注释扫描一个方法,而不仅仅是 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();
问题出在 getAnnotation
,因为它需要具体注释 class 才能知道它有类似 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);