Search code examples
javaspringspring-mvcaspectjaudit-trail

Capturing Logged In User Page Visits/ clicks on images/hyperlinks/buttons - User Activity Audit Trailing


Currently we are into development phase of our product, and to be frank numerous controllers/services has already been written. We are using Spring MVC, Core, Aspect, Security etc along with Hibernate, JQuery etc.

Now we have a requirement to capture Logged in user activities, such button clicks, menu clicks, hyperlink clicks etc.

One approach is i use Spring Aspect, and create my own annotation or use in built if any in spring. But the issue is, i will have to manually add it to all the controllers in my application.Refer this.

is there something available on the Global level, somewhere around dispatcher servlet, when the request is processed. (Just like @ControllerAdvice with @ExceptionHandler)


Solution

  • Pointcuts in Spring AOP or AspectJ cannot only be based on manually added annotations, but also on other common traits of the methods you want to intercept, such as

    • package name patterns,
    • class name patterns,
    • method name patterns,
    • method signatures (certain parameter types),
    • class hierarchies (e.g. macht all subclasses of a certain class or interface)

    and any combinations thereof. You can probably get pretty far with that. But in order to give a more concrete answer I would have to know more about your code.


    Update: Now that you told me the common denominator, I have an idea for you:

    package de.scrum_master.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    public aspect RequestMappingInterceptor {
        @Pointcut(
            "within(@org.springframework.stereotype.Controller *) && " +
            "@annotation(requestMapping) && " +
            "execution(* *(..))"
        )
        public void controller(RequestMapping requestMapping) {}
    
        @Before("controller(requestMapping)")
        public void advice(RequestMapping requestMapping, JoinPoint thisJoinPoint) {
            System.out.println(thisJoinPoint);
            System.out.println("  " + requestMapping);
            System.out.println("  " + requestMapping.method()[0]);
        }
    }
    

    This example intercepts all public methods in all controllers and additionally binds the request mapping annotation to a parameter which you can easily evaluate.