Pergunta

On PAGE A is a table with some data from the database.
by clicking on a row, the page will be forwarded to PAGE B and in the controller the entity will be injected

@DataModelSelection(value = ENTITY_LIST_NAME)
@Out(value = ENTITY_NAME, scope = ScopeType.CONVERSATION, required = false)
private Entity entity;

this works as it should.

The problem is, that our users seems to use bookmark for PAGE B, so the entity will never be injected because they never visited PAGE A

so they always throw this exception

@In attribute requires non-null value

Is there a global function to catch all @In attribute requires non-null value exceptions and forward the user to PAGE C (startpage)?
(of course i can catch this execption on PAGE B but this happens not only on one page, we want to handle this exception on every page)

we are using: jboss5 + jsf 1.2 + seam 2

UPDATE after the answer of EmirCalabuch:
I also tried the hint from EmirCalabuch with:

<page conversation-required="true" no-conversation-view-id="PageC.xhtml" />

but the problem is, that the conversation is alive at this moment, to this forwarding to pageC never happens...

i also made in the page.xml of this page something like:

<action execute="#{controller.checkIfEntityIsSet()}" />
<navigation>
    <rule if-outcome="HOME">
            <redirect          
             view-id="/pages/home.xhtml"
            />
        </rule>
</navigation>

and in my Controller.java i have somthing like this:

public String checkIfEntityIsSet(){
        if(getEntity() == null){
            return "HOME"; 
        }
        return "";          
    }

but this checkIfEntityIsSet() is never called, because the @In attribute requires non-null value is thrown before... so this was not a help at all...

Foi útil?

Solução 2

i managed it now different:

in the Controller.java i have for the initialization something like this:

@Create
public void initialize() throws MissingMyEntityException {

    if(qualifiedCustomer == null){
        throw new MissingMyEntityException("something wrong");
    }
    ....
}

my MissingMyEntityException.java looks like this:

public class MissingMyEntityException extends Exception {

    private static final long serialVersionUID = 8640645441429393157L;

    public MissingMyEntityException(String message) {
        super(message);
    }

}

and in the pages.xml i have the exception handler like this:

<exception class="com.dw.companyName.view.xyz.exception.MissingMyEntityException">
        <redirect view-id="/pages/home.xhtml">
            <message>something went wrong</message>
        </redirect>
    </exception>

and this fixed the problem.
but thanks for your help, but it was not working your way :(

Outras dicas

Exception handling rules are specified in pages.xml. You could include a rule to catch the org.jboss.seam.RequiredException that is thrown for that type of error and perform your navigation to page C in it.

This however is not a very clean solution as you would bind that exception to that page and most probably you will have this exception elsewhere and would like to redirect to a different page.

A simpler way of achieving the same result is making the conversation required in PageB.page.xml and specifying the view to redirect to when no conversation is active. The page descriptor has an option that allows you to do just that (on PageB.page.xml):

<page conversation-required="true" no-conversation-view-id="PageC.xhtml" />

This tells Seam that if a user tries to display page B and there is no conversation active (which happens when the user gets there from a bookmark), then redirect the user to PageC.xhtml.

Anyway, it takes very little effort to make the page bookmarkable (if you feel your users will be bookmarking it a lot), using page parameters and actions, for example:

In your list page A, instead of an h:commandLink or h:commandButton for each of the rows that take you to page B, use s:link or s:button:

<h:dataTable var="var" value="#{myList.dataModel}">
...
  <s:link value="PageB.xhtml">
      <f:param name="id" value="#{var.id}" />
  </s:link>
...
</h:dataTable>

This will create a link to Page B for each of the entities in the list, passing its ID (for example, PageB.seam?id=1 in the first row, PageB.seam?id=2 in the second and so on. These links are bookmarkable.

On PageB.page.xml declare the parameter:

<param name="id" value="#{myHomeComponent.id}" />

Where myHomeComponent is a component of type EntityHome<YourEntity>. You can then use #{myHomeComponent.instance} inside Page B to access the entity selected.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top