Question

I am using JSF 2.x in my project.

I have two pages and two managed beans (request scoped) for these two pages.

Page 1 is loaded after user clicks on a link on Home page. This link calls view() method of Bean1 (with request parameter ID=some value) in which we load some data from DB (based on ID) and then redirects to page 1 where this data is displayed.

Later, user navigates from page 1 to page 2 and here we pass the same ID to the page 2.

On page 2, user enters data and clicks on Save button. This will call saveDetails() method of Bean 2.

After the saveDetails() method I want to redirect to page 1 by calling Bean1's view() method and passing the ID as request parameter. I cannot redirect directly to page1 because then there will be no data to display as the bean1 is request scoped.

Hence, I want to call bean1.view() with request parameter ID. I.e. I want to achieve the same behavior as if user has clicked on the link on Home page.

How to achieve this?

Here is the code so far:

    @ManagedBean
@Component
@RequestScoped
@Scope("request")
// bean for page1
public class ModifyCDSPageBean extends BasePageBean {
private DisplayTicket ticket;
private String selectedCDS;
...
...
// CDS List
private static Map<String, String> cdsList = new LinkedHashMap<String, String>();

@Autowired
TicketConsoleGTRDao ticketConsoleGTRDao;

private static final Logger LOGGER = Logger.getLogger(ModifyCDSPageBean.class);

public String viewTicketDetails() {
    populateCDSList();

    ....
    // Method updated to set DisplayInfoTravail
    String id_incident = getRequestParameterValue(TicketConstants.ID_INCIDENT);
    List<InfoTravail> travailsList = 
    ticketConsoleGTRDao.findMatchingTrvailInformation(id_incident);

    ....

    return NavigationConstants.PAGE_MODIFY_CDS;
}
...
...
}


@ManagedBean
@Component
@RequestScoped
@Scope("request")
//Bean for page 2
public class CreateInfoTravailPageBean extends BasePageBean {

private String selectedTypeInfoTravail;

...
...

@Autowired
TicketConsoleGTRDao ticketConsoleGTRDao;

private static final Logger LOGGER = Logger.getLogger(CreateInfoTravailPageBean.class);

public String viewInfoTravail() {
    populateTypeInfoTravailList();
    ...
    ...
    return NavigationConstants.PAGE_CREATE_INFO_TRAVAIL;
}

public String saveInfoTravail() {
    String idIncident = getRequestParameterValue(TicketConstants.ID_INCIDENT);
    infoTravail.setTicketId(idIncident);
    infoTravail.setDate_creation(formatter.format(new Date()));

    // HERE I WANT TO CALL ModifyCDSPageBean.viewTicketDetails() method 
    // pass id_incident as request parameter while making this call
    // because if you check  ModifyCDSPageBean.viewTicketDetails above it 
    // looks for request parameter id_incident

}
Was it helpful?

Solution

Re-reading your requirements, it sounds like you want a page initialization code. That is, turn around the flow and don't let entry-points into your page1 call the bean's code, let the bean do that itself:

@ManagedBean @RequestScoped
public class ModifyCDSPageBean {
    @Inject @Param(name = TicketConstants.ID_INCIDENT)
    private ParamValue<Long> myParam;

    @Autowired
    private TicketConsoleGTRDao dao;

    private List<InfoTravail> travailsList;

    @PostConstruct
    public void init() {
        if (myParam.getValue() != null) {
            // do stuff based on the param being set
            travailsList = dao.findById(myParam.getValue());
        }
    }
    // getter for travailsList
}

And then include the parameter in your navigation from bean2:

public class Bean2 {
    public String save() {
        String idIncident = getRequestParameterValue(TicketConstants.ID_INCIDENT);
        // do stuff and then return to page1, passing parameter ID_INCIDENT
        return String.format("page1?faces-redirect=true&%s=%s", 
            TicketConstants.ID_INCIDENT, idIncident);
}

If you don't need to execute your view preparation code every time you create ModifyCDSPageBean (ie, if it's used on other pages, too), look into calling it on your page. If you've got JSF-2.2, try <f:viewAction action="#{modifyCDSPageBean.init}"> or on older versions, <f:event listener="#{modifyCDSPageBean.init()}" type="preRenderView">.

Note that @PostConstruct with a @RequestScoped bean will re-create the bean with each AJAX-request, which is probably not what you want. In that case, try @ViewScoped.

My code example uses omnifaces' @Param for my lack of knowledge of spring. Maybe they have something similar in the toolkit already (or just call your getRequestParameterValue from the bean method).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top