Flagman
Flagman

Reputation: 446

JSF 2.0 Navigation-Rules doesn't work

I have a Problem with my Navigation Rule. The redirect doesnt't work, but the Return-Value for the Navigation rule works.

Here is my faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file is not required if you don't need any extra configuration. -->
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

    <!-- This descriptor activates the JSF 2.0 Servlet -->
    <validator>
        <validator-id>usernameValidator</validator-id>
        <validator-class>ch.akros.emember.validator.UsernameValidator</validator-class>
    </validator>

    <!-- Write your navigation rules here. You are encouraged to use CDI for 
        creating @Named managed beans. -->
    <navigation-rule>
        <from-view-id>index.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>registration</from-outcome>
            <to-view-id>/pages/registration/registration.xhtml</to-view-id>
            <redirect />
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/pages/registration/verification.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>registrationDetail</from-outcome>
            <to-view-id>/pages/registration/registrationDetail.xhtml</to-view-id>
            <redirect />
        </navigation-case>
    </navigation-rule>
</faces-config>

And here is my Bean:

package ch.akros.emember.controller;

import javax.annotation.PostConstruct;
import javax.enterprise.inject.Model;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import ch.akros.emember.facade.ClubFacadeRemote;
import ch.akros.emember.facade.UserFacadeRemote;
import ch.akros.emember.model.Club;
import ch.akros.emember.model.User;

// The @Model stereotype is a convenience mechanism to make this a request-scoped bean that has an
// EL name
// Read more about the @Model stereotype in this FAQ:
// http://sfwk.org/Documentation/WhatIsThePurposeOfTheModelAnnotation
@Model
public class RegistrationController {

   @Inject
   private FacesContext     facesContext;

   @Inject
   private UserFacadeRemote ufr;

   @Inject
   private ClubFacadeRemote cfr;

   private String           verification_key;

   private Club             newClub;

   private User             newUser;

   @Produces
   @Named
   public Club getNewClub() {

      return newClub;
   }

   @Produces
   @Named
   public User getNewUser() {

      return newUser;
   }

   public void register() throws Exception {

      try {
         ufr.saveUser(newUser);

         newClub.setUser(newUser);
         newClub.generateVerificationKey(newUser.getEmail());
         cfr.saveClub(newClub);
         facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Registered!",
               "Registration successful"));
      } catch (Exception e) {
         String errorMessage = getRootErrorMessage(e);
         FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Registration Unsuccessful");
         facesContext.addMessage(null, m);
      }
   }

   @PostConstruct
   public void init() {

      newClub = new Club();
      newUser = new User();
   }

   private String getRootErrorMessage(Exception e) {

      // Default to general error message that registration failed.
      String errorMessage = "Registration failed. See server log for more information";
      if (e == null) {
         // This shouldn't happen, but return the default messages
         return errorMessage;
      }

      // Start with the exception and recurse to find the root cause
      Throwable t = e;
      while (t != null) {
         // Get the message from the Throwable class instance
         errorMessage = t.getMessage();
         t = t.getCause();
      }
      // This is the root cause message
      return errorMessage;
   }

   public String saveUser() {

      return "registrationDetail";
   }

   /**
    * Get the verification_key.
    * 
    * @return verification_key
    */
   public String getVerification_key() {

      return verification_key;
   }

   /**
    * Set the verification_key.
    * 
    * @param verification_key, the verification_key to set
    */
   public void setVerification_key(String verification_key) {

      this.verification_key = verification_key;
   }
}

From my Page it calls the Method saveUser() amd this works. But the redirect won't work.

Has someone a clue for me, what if goes wrong here?

Upvotes: 0

Views: 1280

Answers (1)

elbuild
elbuild

Reputation: 4899

As Sébastien Vanmechelen rightly pointed out in JSF 2.2 the faces-config.xml is non mandatory (and it's overcomplicated I may add).

Just change your saveUser() method from:

public String saveUser() {

      return "registrationDetail";
}

to:

public String saveUser() {
      return "/pages/registration/registrationDetail.xhtml?faces-redirect=true";
}

It will work from any view without the need of adding lines into the faces-config.xml.

There's something I still don't get in your code. Why are you using a Managed Bean method to do simple navigation (no business logic involved). You can just use an h:outputLink or even an HTML tag to redirect the user.

Upvotes: 1

Related Questions