Seam 2.2.0.GA exception handling - reloaded
seameddie Jul 15, 2011 8:20 AMHello.
This is my second post about this topic, the first was not so very succesful, because it was a bit confuse:
http://seamframework.org/Community/ExceptionHandlingQuestion
Sorry for that.
So now i am going to describe once again in detail what i did and what my problem (which should by easy to solve for anyone having more experience in seam than me, im a rookie) is:
I used seam-gen from Seam 2.2.0.GA to create a sample project (to be run in JBoss 5.1.0.GA). After that, i created a new action via
seam new-action
named listOffers, which generated the following xhtml page:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:a="http://richfaces.org/a4j" template="layout/template.xhtml"> <ui:define name="body"> <rich:panel> <f:facet name="header">listOffers</f:facet> <h:form id="listOffersForm"> <h:commandButton id="listOffers" value="listOffers!" action="#{listOffers.listOffers}"/> </h:form> </rich:panel> </ui:define> </ui:composition>
My plan was to display some entities looking like this
package org.jboss.seam.example.booking.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.TableGenerator; import org.jboss.seam.annotations.Name; @Entity @Name("specialOffer") @TableGenerator(name = "UniqueIdGenerator", table = "ID_GEN", pkColumnName = "ID_NAME", valueColumnName = "ID_VAL", pkColumnValue = "globalkey", allocationSize = 10) public class SpecialOffer { private Long id; private String name; private String description; @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
in this page, so i modified it like this:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:a="http://richfaces.org/a4j" template="layout/template.xhtml"> <ui:define name="body"> <rich:panel> <f:facet name="header">listOffers</f:facet> <h:form id="listOffersForm"> <h:dataTable id="offers" value="#{offers}" var="offer" rendered="#{offers.rowCount>0}"> <h:column> <f:facet name="header">Name</f:facet> #{offer.name} </h:column> <h:column> <f:facet name="header">Description</f:facet> #{offer.description} </h:column> </h:dataTable> </h:form> </rich:panel> </ui:define> </ui:composition>
Below is the source code of the stateful session bean
package org.jboss.seam.example.booking.action; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.datamodel.DataModel; import org.jboss.seam.annotations.datamodel.DataModelSelection; import org.jboss.seam.example.booking.model.SpecialOffer; import org.jboss.seam.international.StatusMessages; import org.jboss.seam.log.Log; @Stateless @Name("listOffers") public class ListOffersBean implements ListOffers { @Logger private Log log; @In StatusMessages statusMessages; @DataModel private List<SpecialOffer> offers; @DataModelSelection private SpecialOffer offer; @PersistenceContext private EntityManager em; public SpecialOffer getOffer() { return offer; } @Factory public void getOffers() { offers = em.createQuery("select s from SpecialOffer s").getResultList(); } }
and its local interface
package org.jboss.seam.example.booking.action; import javax.ejb.Local; import org.jboss.seam.example.booking.model.SpecialOffer; @Local public interface ListOffers { public void getOffers(); public SpecialOffer getOffer(); }
bound to the view (which are fetching the data from the database).
Everything works fine, the data from the table is displayed in my browser (Internet Explorer 7.5730.13) when invoking the action.
My problem is, that when i restrict the access to the stateful session bean like this
@Stateful @Name("hotelBooking") @Restrict("#{identity.loggedIn}") public class HotelBookingAction implements HotelBooking { //nothing modified in here, i just added the restrict annotation above }
and i try to access the action without being logged in, the (logically) following
org.jboss.seam.security.NotLoggedInException
is not handled correctly as defined in the projects pages.xml (which i DID NOT modify):
<exception class="org.jboss.seam.security.NotLoggedInException"> <redirect view-id="/login.xhtml"> <message severity="warn">#{messages['org.jboss.seam.NotLoggedIn']}</message> </redirect> </exception>
I am NOT getting redirected to the login screen, instead of that i just get a stack trace in my browser:
org.jboss.seam.security.NotLoggedInException at org.jboss.seam.security.Identity.checkRestriction(Identity.java:217) at org.jboss.seam.security.SecurityInterceptor$Restriction.check(SecurityInterceptor.java:113) at org.jboss.seam.security.SecurityInterceptor.aroundInvoke(SecurityInterceptor.java:160) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54) ...
Does anyone know why the redirect does not work?
Thanks in advance,
Stefan