They are only in scope throughout the life of the request, where as session attributes persist across requests. Attributes should live for the shortest amount of time you can get away with or you may end up with hard to track down errors and spaghetti code where you have to forcibly remove a session attribute when you've finished with it (because
you should have put it as a request attribute).
Liken it to;
Application scope -> Global Variable (public static)
Session scope -> Instance variable (class member)
Request scope -> Method local variable