Dynamic Menu Implementation for Spring MVC / AOP Application

I want to implement a dynamically changing menu (updating whenever an annotated method or controller is added) for my Spring MVC application.

I want to introduce a new annotation ( @RequestMenuMapping ) that will go to @Controller beans, and their methods (like @RequestMapping work).

Heres is what I want, a User class creating a menu like

 Users Index | List | Signup | Login 

with the following code:

 @Controller @RequestMapping("user") @RequestMenuMapping("Users") public class User { @RequestMapping("") @RequestMenuMapping("Index") public String index(/* no model here - just show almost static page (yet with JSP checks for authority)*/) { return "user/index.tile"; } @RequestMapping("list") @RequestMenuMapping("List") public String list(Model model) { model.addAttribute("userList",/* get userlist from DAO/Service */); return "user/list.tile"; } @RequestMapping("signup") @RequestMenuMapping("Signup") public String signup(Model model) { model.addAttribute("user",/* create new UserModel instance to be populated by user via html form */); return "user/signup.tile"; } @RequestMapping("login") @RequestMenuMapping("Login") public String login(Model model) { model.addAttribute("userCreds",/* create new UserCreds instance to be populated via html form with login and pssword*/); return "user/login.tile"; } } 

I think Spring AOP can help me specify methods with the @RequestMenuMapping annotation @RequestMenuMapping and through @AfterReturning add something that represents the website menu for modeling.

But this raises two questions:

  • How can I get an instance of Model in the @AfterReturning method if it is not in the adviced method (as in .index() )?
  • How can I get all methods (like in java reflection Method ) and classes (like in java reflection Class ) annotated with @RequestMenuMapping in order to build a full menu index?
+4
source share
3 answers

InterceptorDemo:

 @Aspect @Component public class InterceptorDemo { @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)") public void requestMapping() { } @Pointcut("@annotation(you.package.RequestMenuMapping)") public void requestMenuMapping() { } @AfterReturning("requestMapping() && equestMenuMapping()") public void checkServer(JoinPoint joinPoint,Object returnObj) throws Throwable { Object[] args = joinPoint.getArgs(); Model m = (Model)args[0]; // use joinPoint get class or methd... } } 

If you want to intercept the Contoller with you, you can create another pointcut and the ProceedingJoinPoint object can get what you want.

+1
source

I think that it would be best to become a bean mail processor to scan all controller classes for @RequestMenuMapping and HandlerInterceptor to add menu items to each model card.

+2
source

1: ModelAndView create an object org.springframework.web.servlet.DispatcherServlet.doDispatch()

 // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation? if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } 

So, you can intercept the handle method after saving or overriding the method.

Q2: As far as I know, there are two ways to get annotation methods.

1. Use AOP: You can declare a pointcut as follows:

 @Pointcut("@annotation(you.package.RequestMenuMapping)") public void requestMenuMappingPountcut() { } 

2. Use reflection.

 Class clazz = Class.forName(classStr); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(RequestMapping.class) && method.isAnnotationPresent(RequestMenuMapping.class)) { // do something } } 
+1
source

All Articles