There's not a really good answer to that. Currently, I'm developing a J2EE site, and I'm only using JSP's.
The goal of a well-designed J2EE site is to seperate business logic from site layout, and maintain the MVC model. The problem many people have with JSP's are that it's just too convient to slip into doing business logic in them. So a variety of other technologies have been made that enforce boundaries more explicitly, such as
Jakarta Struts,
JavaServer Faces, and
Jakarta Turbine/
Velocity.
The way I have designed my site, in ad-hoc fashion, is to have 2 types of JSP's, one where something is displayed, and one which processes form data or performs some type of action. Anything involving business logic is initiated in the latter type, but the guts of it is performed in beans. For instance, I'll call an addUser(uid, pass) in a JSP, but the actual adding of a user to a database will occur in the bean.
A goal to strive for is that you should be able to give a quick training session to a web-coder so they can update the JSP as needed, but won't have to/be able to alter the business logic. If you move all that stuff over to servlets, you've ensured that some HTML monkey with a crash-course in JSP won't be able to screw things up. That's also why, despite the fact I don't use them personally, I think people should use JSP Tags instead of escaped code; it enforces the boundary between html monkey and code monkey.