Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AOP for Spring Controllers

Spring's AOP functionality is pretty great, and it makes it easy to add cool and useful annotations to controllers. For example, I wrote an @Authenticated annotation that either allows authenticated users through to the controller method or redirects to the login page. Fun stuff.

However, Spring's controllers can return all sorts of different types. They can return Strings, ModelAndView objects, or even void. There are methods in my code base that use all three types. However, I'd like to change my @Authenticated annotation to render and return a particular page, which I was hoping to do by returning a ModelAndView object. Is the only way to accomplish this by requiring all of my controller methods to return a ModelAndView?

Example of a controller I'd like to have:

@Controller
public class MyController() {
   @Authenticated
   @RequestMapping("/myscore")
   public String myScorePage(ModelMap model) {
      return "myScorePage";
   }

   @Authenticated
   @RequestMapping("/anotherPage")
   public ModelAndView something() {
      return new ModelAndView("anotherPage",someModelStuff());
   }
}

@Aspect
public class NotVeryUsefulAspect {
   @Around("@annotation(Authenticate)")
   public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
       if( isAuthenticated() ) {
           return pjp.proceed();
       } else {
           return /* Oh no what goes here, I want to render a FAILURE page without redirecting */
       }
   }

}
like image 914
Brandon Yarbrough Avatar asked Nov 04 '22 22:11

Brandon Yarbrough


1 Answers

Ha, figured it out!

I decided to use the ProceedingJoinPoint passed to the aspect method to figure out the return type of the original method. Then I made a set of possible "failure" results for the aspect method based on what type of return is passed. For example, if the method originally returned a String, I return "failure_page", and if the method returned a ModelAndView, I return a new ModelAndView("failure_page").

Works quite well! Unfortunately, I may not have an opportunity to set a model object if it returns a string and doesn't take a ModelMap as a parameter, but I can deal with that for an error page just fine.

like image 192
Brandon Yarbrough Avatar answered Nov 11 '22 12:11

Brandon Yarbrough