We are trying to use reflection to extract the exact mapped values to our methods. The code structure in the target module consists of multiple classes as follows -
@Controller
@RequestMapping(value = "/questions")
public class XYZController {
@RequestMapping(value = "/ask")
public boolean myMethod1() {..}
@RequestMapping(value = "/{questionNo.}/{questionTitle}")
public MyReturnObject myMethod2(){..}
}
What we are trying to grep here is the list of endpoints like /questions/ask
and /questions/{questionNo.}/{questionTitle}
for which the code we tried to execute filters all such classes based on the @Controller
annotation and at the same time we are able to get the list of all the endpoints separately. The code we have tried so far is -
public class ReflectApi {
public static void main(String[] args) {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
final List<String> filteredClasses = new ArrayList<>();
scanner.addIncludeFilter(new AnnotationTypeFilter(Controller.class));
Set<BeanDefinition> filteredPackage = scanner.findCandidateComponents("com.package.test");
// gives me a list of all the filtered classes
filteredPackage.stream().forEach(beanDefinition -> filteredClasses.add(beanDefinition.getBeanClassName()));
// call to get the annotation details
filteredClasses.stream().forEach(filteredClass -> getEndPoints(filteredClass));
}
public static void getEndPoints(String controllerClassName) {
try {
Class clazz = Class.forName(controllerClassName);
Annotation classAnnotation = clazz.getDeclaredAnnotation(RequestMapping.class);
if (classAnnotation != null) {
RequestMapping mappedValue = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
System.out.println("Controller Mapped -> " + mappedValue.value()[0]); //This gives me the value for class like "/questions"
runAllAnnotatedWith(RequestMapping.class);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// followed from a SO reference
public static void runAllAnnotatedWith(Class<? extends Annotation> annotation) {
Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forJavaClassPath())
.setScanners(new MethodAnnotationsScanner()));
Set<Method> methods = reflections.getMethodsAnnotatedWith(annotation);
methods.stream().forEach(m -> {
if (m != null) {
RequestMapping mappedValue = m.getAnnotation(RequestMapping.class); //this is listing out all the @RequestMapping annotations like "/questions" , "/ask" etc.
System.out.println(mappedValue.value()[0]);
}
});
}
}
But the missing part is the concatenation of the class to method RequestMapping value here.
How do we loop inside a class to search annotations only from its methods?
Or is there any simpler way of doing this from what we are using?
References used - Scanning Java annotations at runtime && How to run all methods with a given annotation?
Aucun commentaire:
Enregistrer un commentaire