Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

This is the solution I came up with to log user requests:


@Startup
@Scope(ScopeType.APPLICATION)
@Name("mypackage.loggingFilter")
@BypassInterceptors
@Filter
public class LoggingFilter extends AbstractFilter
{

    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
	    throws IOException, ServletException
    {
	if (HttpServletRequest.class.isAssignableFrom(arg0.getClass()))
	{
	    HttpServletRequest r = (HttpServletRequest) arg0;
	    try
	    {
		Lifecycle.beginCall();
		HttpSession ses = r.getSession(false);
		if (ses != null)
		{

		    UserLog log = (UserLog) ses.getAttribute("userLog");
		    if (log != null)
		    {
			UserTransaction transaction = (UserTransaction) Component
				.getInstance("org.jboss.seam.transaction.transaction");
			try
			{

			    transaction.begin();
			    EntityManager e = (EntityManager) Component
				    .getInstance("entityManager");
			    e.joinTransaction();
			    log.setLastRequest(new Date());
			    e.merge(log);
			    e.flush();
			} finally
			{
			    transaction.commit();
			}
		    }
		}
	    } catch (Exception e)
	    {
		System.out.println("COULD NOT LOG USER ACTIVITY " + e.getMessage());
	    } finally
	    {
		Lifecycle.endCall();
	    }
	}
	arg2.doFilter(arg0, arg1);
    }

}

In this simple case all it is updating the last request time for a session scoped UserLog entity. A few things to note:

  • Logging takes place in a separate transaction
  • The session and conversation context will not be available, session scoped components can be accessed using the servlet context as seen here
2 comments:
 
14. Jul 2010, 17:13 America/New_York | Link

You can get a concurrent access exception on the UserLog entity with this approach, when multiple users access your application.

So you need to lock the UserLog before persisting it.

Anyways, another approach is to update the UserLog in the filter and keep the changes in the session and (bulk) flush/persist the whole stuff after the users logs out (by making an observer on the logout event) or after some interval.

 
15. Aug 2011, 17:03 America/New_York | Link
HttpServletRequest.class.isAssignableFrom(arg0.getClass())

should be written as

arg0 instanceof HttpServletRequest