Spring / AOP: the best way to implement an action log in a database

I went through several Spring / AOP tutorials and got a little familiar with the relevant concepts.

Now, coming to my requirements, I need to create an Activity Log implementation that saves the actions of a registered user in the database, which can vary from applying for a service or creating new users in case of users Admin, etc. When calling any method that has an annotation (say @ActivityLog), this information should be stored in the form of actorId, actionComment, actionTime, actedUponId, ... etc.

Now, if I create a POJO class (which is displayed in a table ActivityLogin the database) and want to save this data from Advice(preferably using the same transaction as the method, the method uses the @Transactionalannotation), how do I actually populate the variables in this POJO? I can probably get actorIdfrom the session object, or actionTimemaybe just be new Date(), but what about dynamic values ​​for actionComment/ actedUponId?

Any help would be brilliant! (By the way, I have a requirement not to use Hibernate Interceptors.)

+3
source share
3 answers

Here is a complete example:

@Aspect
@Component
public class WebMethodAuditor {

protected final Log logger = LogFactory.getLog(getClass());

public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

@Autowired
AuditRecordDAO auditRecordDAO; 

@Before("execution(* com.mycontrollers.*.*(..))")
public void beforeWebMethodExecution(JoinPoint joinPoint) {
    Object[] args = joinPoint.getArgs();
    String methodName = joinPoint.getSignature().getName();
    User principal = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    Timestamp timestamp = new Timestamp(new java.util.Date().getTime());
    // only log those methods called by an end user
    if(principal.getUsername() != null) {
        for(Object o : args) {
            Boolean doInspect = true;
            if(o instanceof ServletRequestDataBinder) doInspect = false;
            if(o instanceof ExtendedModelMap) doInspect = false;
            if(doInspect) {
                if(o instanceof BaseForm ) {
                    // only show form objects
                    AuditRecord ar = new AuditRecord();
                    ar.setUsername(principal.getUsername());
                    ar.setClazz(o.getClass().getCanonicalName());
                    ar.setMethod(methodName);
                    ar.setAsString(o.toString());
                    ar.setAudit_timestamp(timestamp);
                    auditRecordDAO.save(ar);
                }
            }
        }
    }
}

}
+2
source

actionComment actedUponId ( , ), @Around :

@Around("@annotation(ActivityLog) && args(actionComment,actedUponId)")
public Object logActivity(ProceedingJoinPoint pjp,
        String actionComment, String actedUponId) throws Throwable {
    // ... get other values from context, etc. ...
    // ... write to log ...
    pjp.proceed();
}

args pointcut , , , bean, , .

, , . bean Spring Ordered order <tx:annotation-driven/>. ( , , , ...)

+2

org.aspectj.lang.JoinPoint . , toShortString(). / method-name=comments. POJO.actionComment.method-name POJO.actedUponId.

, , , @Transactional.

0
source

All Articles