jsf2.0 - как получить значения в bean-объекте другой jsf-страницы в области запроса

У меня есть две страницы myaccount.xhtml и selectbank.xhtml На странице моего аккаунта есть одна опция для пополнения счета, в которой пользователь вводит сумму, когда пользователь нажимает кнопку отправки, после чего он переходит на страницу выбора банка, используя следующий метод bean.

public String gotoPayMethod() {
    FacesMessage doneMessage=new FacesMessage("Redirecting to Payment Type Page");
    FacesContext.getCurrentInstance().addMessage(null, doneMessage);
    return "SelectBank";
}

Когда пользователь перейдет к выбору банка, он должен будет указать способ оплаты, но на этой странице он показывает нулевую сумму, которая была введена на предыдущей странице. Обе страницы используют один и тот же компонент, и область действия компонента - это область запроса.

Так как я могу получить доступ к этому значению, не передавая эти значения через метод URL GET. Просто для моего удовлетворения я использовал сессионную область, тогда она работала, но я знаю, что это неправильный способ, потому что я начинаю использовать сессионную область для каждой страницы, тогда она не будет эффективной. Спасибо

3 ответа

Решение

Хорошо, если ваши бобы RequestScoped чем у вас нет одного и того же компонента для обеих страниц. Эти бины воссоздаются для каждого запроса, поэтому вы должны передавать параметры. Изменить заявление о возврате вашего gotoPayMethod() чтобы:

return "SelectBank?faces-redirect=true&includeViewParams=true";

и на selectbank.xhtml добавлять:

<f:metadata>
  <f:viewParam name="amount" value="#{bean.amount}" />
</f:metadata>

Приспособьте это к своей собственности и имени боба.

Если использование параметров не является решением, вы можете добавить этот параметр в сеанс и удалить его из сеанса во втором компоненте, когда получите его:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("amount", amount);
((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().removeAttribute("amount");

Вторая конструкция для удаления атрибута необходима как Map вернулся из getSessionMap() неизменен.

Вы можете использовать #{flash} объект, который будет хранить ваши данные до следующего просмотра. Таким образом, вам не нужно иметь дело с параметрами просмотра.

Детали из myaccount.xhtml:

<h:form>
    <h:outputText value="Enter amount: " />
    <h:inputText value="#{flash.amount}" />
    <br/>
    <h:commandButton value="Go to payment method" action="#{bean.gotoPayMethod}" />
<h:form>

Bean обоих взглядов:

@ManagedBean
@RequestScoped
public class Bean {

    @ManagedProperty("#{flash}")
    private Flash flash;

    private int amount = -1;

    public Bean () {   }

    public String getAmount() {
        if(amount == -1) {
            int val = Integer.parseInt((String)flash.get("amount"));
            flash.keep("amount");
            amount = val;
        }
        return amount;
    }

    public Flash getFlash() {
        return flash;
    }

    public void setFlash(Flash flash) {
        this.flash = flash;
    }

    public String gotoPayMethod() {
        //do business job
        return "SelectBank?faces-redirect=true";
    }

}

Детали из selectbank.xhtml:

<h:outputText value="Amount entered by user is #{bean.amount}" />

Ваш вариант использования не простой цикл запрос / ответ, срок службы более одного ответа на запрос, что делает его кандидатом в область действия сеанса.

Использование скрытых переменных или параметров GET в URL не является хорошей практикой, особенно для банковского приложения. Там, где безопасность так важна, не идите на компромисс с небольшим отпечатком памяти.

Если карта объема флеш-памяти упрощает случай, вы можете использовать ее, но я бы не стал этого делать.

Обновление: забыл упомянуть, что вы также можете проверить область беседы.

Другие вопросы по тегам