4

We need to call a action method while invoking the first page of the application. For example, the first page is index.jsp, when we are directly calling this page the action method is not called. To achieve that, we have written another page where it uses java script to click on the button and call the action method, that navigates to the index.jsp.

I feel that there should be proper way in JSF to achieve this task. What is the bet way to do that? I have told the team that we can call the action method in the constructor while loading the page. Is it the correct way? What are the possible solutions?

Krishna
  • 6,706
  • 15
  • 64
  • 79

2 Answers2

11

Just do the job in @PostConstruct method of an application scoped bean which is is eagerly constructed or which is at least bound to the page.

@ManagedBean(eager=true)
@ApplicationScoped
public class Bean {

    @PostConstruct
    public void init() {
        // Here.
    }

}

Alternatively, if JSF (read: the FacesContext) has no relevant role in the actual job, you can also use a ServletContextListener.

@WebListener
public class Config implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
        // Do stuff during webapp startup.
    }

    public void contextDestroyed(ServletContextEvent event) {
        // Do stuff during webapp shutdown.
    }

}

If you're not on Servlet 3.0 yet, register it in web.xml as follows.

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Just to be clear you(I know BalusC knows this) if your doing any dependency injection you need to annotate a method with @PostConstruct instead of putting it in the constructor. – Drew H Jan 31 '11 at 03:39
3

Using JSF 2.0

If you want to take some action when your application starts (even if is not yet accesed ), you can use a SystemEventListener and subscribe it to PostConstructApplicationEvent.

Example of the listener:

package listeners;

import javax.faces.application.Application;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ListenerFor;
import javax.faces.event.PostConstructApplicationEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;

public class MySystemListener implements SystemEventListener{

    @Override
    public void processEvent(SystemEvent event) throws AbortProcessingException {
        System.out.println("started");
    }

    @Override
    public boolean isListenerForSource(Object source) {
        return source instanceof Application;
    }

}

To suscribe you have to include this fragment in the faces-config.xml

<application>
    <system-event-listener>
        <system-event-listener-class>
            listeners.MySystemListener
        </system-event-listener-class>
        <system-event-class>
            javax.faces.event.PostConstructApplicationEvent
        </system-event-class>
    </system-event-listener>
</application>

And if you want to take the action when the user enters to a specific page, you could use another system event and f:event tag to receive a notification before the page is displayed.

For example:

...
<h:body>
   <f:event type="preRenderView" listener="#{bean.action}"/>
   <h:form>
      <!--components-->
   </h:form>
</h:body>
...

Here are more details on using system events: http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#system-events.

In JSF 1.2, one way I think you could receive a notification will be with PhaseListener's and check the id of the view currently rendering.

victor herrera
  • 966
  • 8
  • 7