flash.keep & flash.setKeepMessages(true) при перенаправлении

Я рассматриваю пример из книги Ангела Леонарда " Освоение Java Server Faces 2.2".

Автор демонстрирует на примере, как сохранить данные для следующего запроса на перенаправление при создании компонента: @RequestScoped,

Это код для index.xhtml-

<h:body>
    <f:metadata> 
        <f:event type="preRenderView" 
            listener="#{playersBean.pullValuesFromFlashAction}"/> 
    </f:metadata>
    <h:messages />  
    <h:form>                       
        Name: <h:inputText value="#{playersBean.playerName}"/>
        Surname: <h:inputText value="#{playersBean.playerSurname}"/>
        <h:commandButton value="Register" 
            action="#{playersBean.addValuesToFlashAction()}"/>          
    </h:form>
</h:body>

terms.xhtml-

<h:body>
    <h:messages />  
    Hello, <h:outputText value="#{flash.keep.playerName} #{flash.keep.playerSurname}"/>    
    <br/><br/>Terms &amp; Conditions ... ... ... ... ...
    <h:form>
        <h:commandButton value="Reject" 
            action="#{playersBean.termsRejectedAction()}" />
        <h:commandButton value="Accept" 
            action="#{playersBean.termsAcceptedAction()}" />
    </h:form>
</h:body>

done.xhtml-

<h:head>
    <title></title>
</h:head>   
<h:body>
    <f:metadata> 
        <f:event type="preRenderView" 
            listener="#{playersBean.pullValuesFromFlashAction}"/> 
    </f:metadata>
    <h:messages />  
    <h:outputText value="#{playersBean.playerName} #{playersBean.playerSurname}"/> 
        successfully registered!           
</h:body>

И бэк-бэк

@ManagedBean
@RequestScoped
public class PlayersBean {

    private final static Logger logger = Logger.getLogger(PlayersBean.class.getName());
    private String playerName;
    private String playerSurname;
    public PlayersBean() {
    }
    public String getPlayerName() {
        return playerName;
    }
    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }
    public String getPlayerSurname() {
        return playerSurname;
    }
    public void setPlayerSurname(String playerSurname) {
        this.playerSurname = playerSurname;
    }
    public String addValuesToFlashAction() {

        Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
        flash.put("playerName", playerName);
        flash.put("playerSurname", playerSurname);
        return "terms?faces-redirect=true";
    }
    public void pullValuesFromFlashAction(ComponentSystemEvent e) {
        Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
        playerName = (String) flash.get("playerName");
        playerSurname = (String) flash.get("playerSurname");
    }
    public String termsAcceptedAction() {
        Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();

        flash.setKeepMessages(true);
        pullValuesFromFlashAction(null);

        //do something with firstName, lastName 
        logger.log(Level.INFO, "First name: {0}", playerName);
        logger.log(Level.INFO, "Last name: {0}", playerSurname);

        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Terms accepted and player registered!"));
        return "done?faces-redirect=true";
    }
    public String termsRejectedAction() {
        Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();

        flash.setKeepMessages(true);
        pullValuesFromFlashAction(null);

        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Terms rejected! Player not registered!"));
        return "index?faces-redirect=true";
    }
}

Я думаю, что в этих двух строчках не было необходимости

flash.setKeepMessages(true);
pullValuesFromFlashAction(null);

так как flash.keep на странице term.xhtml служит той же цели. Автор, похоже, смущен здесь.

Или я полностью неправ, и они определенно служат цели здесь.

1 ответ

Решение

Код, выбранный автором, немного сбивает с толку, с моей точки зрения, однако он делает то, что намеревался сделать.

flash.setKeepMessages (истинный);

Эта строка сообщает JSF, что вы хотите сохранить FacesMessage в объеме вспышки. Это требование при перенаправлении, потому что задействовано более одного последующего запроса, и в противном случае сообщения будут передаваться из одного запроса в другой. Линия необходима.

pullValuesFromFlashAction(нуль);

Строка не делает ничего особенного, просто берет имя и фамилию из области видимости флеш-памяти. Это просто правильно называть это из preRenderView загружать данные bean-компонента из области флэш-памяти, но излишне вызывать их из методов действия (если вы не хотите делать какую-либо запись в журнал, чтобы увидеть, что параметры установлены правильно). В любом случае, если вы начинаете с JSF, я рекомендую вам использовать JSF 2.2, который заменяет preRenderView методы, называемые viewAction,

И последнее, но не менее важное: я бы порекомендовал вам ознакомиться с ответом, который я дал некоторое время назад, и показать пример работы с флеш-областью, вам может быть интересно.

Смотрите также:

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