Lo han dicho ustedes, para eso de las tres capas con patron Front Controller y un código decente con tags en las JSP, Struts es una buena opción, y tengo años trabajando con él, pero ha llegado la hora de divorciarse, les sugiero ir pensando en JavaServer Faces, más comúmente conocido JSF, es el que actualmente uso.
Ventajas:
1. Facilidad para creación de las pantallas ! gestión de nuevos controles, datos tabulares de una mejor manera que como en Struts se hace.
2. Hay algo importante que Struts tuvo la idea de hacerlo, se llama Struts Layouts, JSF funciona similar pero 100 veces más fácil ! ... esto hace más fácil la vida de acomodar los componentes gráficos sin entrar en detalles HTML ....
3. El Controller de JSF es más simple ! ... no hay que crear un Form y Action por cada módulo, o pantalla, ahora se asocia a un Bean de Java "común y silvestre" donde un método retorna un String con el nombre del forward y ya ! ... lo demás es código limpio. Los datos de la pantalla son propiedades del mismo Bean (también pueden usar una delegación, osea una instancia dentro del Bean para guardar los datos, puede ser un TO (Transfer Object) para mandar al servicio posteriormente, llamese EJB, BEAN, WebService.
4. La razón más poderosa de todas: Es de Sun, especificación echa por ellos, y por lo tanto será estándar en las siguiente versión de J2EE. Como dato curioso: esta especificación Faces fue echa por el mismo autor de Struts.
Tiene muchas ventajas más, traten de leer sobre este framework, el los proyectos actuales estoy usando JSF, Struts está pasando a la historia, así de dramatico es el asunto.
Desventajas
1. No soporta tiles, toca hacerle una "maraña" para que funcione, IBM, Exadel entre otros han dado soluciones alternativas, pero no lo soporta directamente la especificación. Sin embargo no es tanta alerta: es versión 1.1 aún, y están en camino versiones con mejoras, quizas tengan tiles para la próxima (Composite View).
2. Algunas cosillas necesitan de crear implementaciones propias para solucionar cosas, ejemplo las validaciones no tienen referencias a los labels, entonces los mensajes de error no traen el nombre del campo con el error implicitamente. Yo lo solucioné implementando un MessageListener simplecito.
APARTE: Respondiendo a la mano de Frameworks que han nombrado, les digo que es de cuidado lo que se decida usar, no sé ustedes, pero la responsabilidad de una decisión tecnologica es grandicima, allá los que solo leen el Java Developer Journal y se enteras de las cosas, pero no les toca cargar con la cruz de escojer una mala plataforma. Para uno ir más seguro es bueno siempre mirar el respaldo de lo que está detrás de estas cosas: Jakarta es buen respaldo, Sun, el grupo JBoss, Hibernate ... entonces, Struts en su momento era la mejor decisión, a lo mejor las demás tenían buenas intensiones pero Struts era algo serio, de igual forma hay muchas implementaciones de JDO, pero Hibernate es excelente ..... mejor dicho, la idea que les quiero vender es, no agarren lo primero que vean por hay que dice hacer algo, tomen experiencias vividas de colegas en otros proyectos, miren sus foros de soporte, quién está detrás, la planeación a largo plazo o si tiene cara de algo pasajero.