【问题标题】:printing bean data in another page (RequestScope)在另一个页面中打印 bean 数据 (RequestScope)
【发布时间】:2013-02-23 06:35:01
【问题描述】:

编辑 4

我想做的是实现 forgotPassword 页面。例如,我以下面的示例为例,我将用户名保留在会话范围内并不是真正的用户相关问题。

index.xhtml 将是我将输入用户名的忘记密码页面。输入用户名后,我会点击Welcome Me - ActionchkMe(),我会检查该用户并在他/她的电子邮件ID 和welcome.xhtml 中发送新密码,我会说Hi User ABC, we have sent new password at asdfasdf@dasf.com


主帖

我正在尝试使用两种情况将数据从一个 bean 打印到另一个。下面是我的代码。

index.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"      
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body>
        <h3>JSF 2.0 Hello World Example - hello.xhtml</h3>
        <h:form>
           <h:inputText value="#{helloBean.name}"></h:inputText>
           <h:commandButton value="Welcome Me - Plain" action="welcome"></h:commandButton>
           <h:commandButton value="Welcome Me - Action" action="#{helloBean.chkMe()}"></h:commandButton>
        </h:form>
    </h:body>
</html>

welcome.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"    
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body bgcolor="white">
        <h3>JSF 2.0 Hello World Example - welcome.xhtml</h3>
        <h4>Welcome --#{helloBean.name}--</h4>
    </h:body>
</html>

HelloBean.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class HelloBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String chkMe() {
        return takeMeToAnotherPage("welcome");
    }

    public String takeMeToAnotherPage(String linkToGo) {
        return linkToGo + "?faces-redirect=true";
    }
}

当我在文本字段中输入文本为Checking 并单击按钮Welcome Me - Plain 时,我在welcome.xhtml 中看到文本为Welcome --Checking-- 文本,但是当我单击Welcome Me - Action 时,我看不到任何文本(我看到Welcome ----)

我不知道为什么会这样。

任何想法/建议为什么会发生这种情况。


编辑 1

我相信这都是?faces-redirect=true造成的,但我必须像不使用?faces-redirect=true一样使用它,地址栏中的URL是以前的URL。

例如如果我在 page1.xhtml 并转到 page2.xhtml,仍然 URL 会显示 page1.xhtml。

所以不知道在这种情况下该怎么办。


编辑 2

好吧,我真正想要做的是忘记密码页面,我将在 index.xhtml 中输入用户名(考虑上面的示例),如果该用户名正确,在welcome.xhtml 中,我将输入Hi User ABC, Please use new password for next login. We have sent you email at blah@blah.com

RequestScope 运行良好,但问题出在 URL 地址上,因此我添加了 ?faces-redirect=true。但是随着它的重定向,http 会话正在关闭,因此在welcome.xhtml 上,我没有得到任何值(这就是上面发生的情况)。

skuntsel 的另一个解决方案是使用 FlashScope但问题是当我刷新welcome.xhtml 时,数据消失了 这让我发疯了。

谁能建议需要做什么?


编辑 3

会话范围的问题如下。

考虑我打开两个选项卡,在两个选项卡上我都有 index.xhtml。在 tab1 上,我输入 Fahim 并单击 Welcome Me - Action。在 tab1 上,welcome.xhtml 出现,我看到文本为 Welcome Fahim这太完美了。

现在我来到 tab2,输入名称为XYZ,然后单击Welcome Me - Action,我得到了welcome.xhtml,我看到文本为Welcome XYZ这也是完美的。

问题是当我回到 tab1 并刷新页面时。当我刷新 tab1 (welcome.xhtml) 时,我看到 Welcome XYZ 这是错误的,之前它是 Welcome Fahim,它应该是 Welcome Fahim

【问题讨论】:

  • Fahim,你应该仔细看看 BalusC 在communication in JSF 上的一篇优秀文章。
  • 你为什么不直接调用@takeMeToAnotherPage' instead of @checkMe' 就像#{helloBean.takeMeToAnotherPage}一样。我猜当你像你一样调用一个方法时,页面已经重定向到takeToAnotherPage .因此,您正在尝试显示在 @RequestScopedBean 的情况下不存在的重定向页面。
  • @Srinivas : 结果还是一样
  • 所有人都可能看到 Edit 2 这正是我想要的。它与用户无关,它与忘记会话有关。我使用的示例仅用于演示目的。
  • @FahimParkar 我认为更新后的答案实际上解决了您的问题(以及原来的问题)。

标签: java jsf jsf-2 scope javabeans


【解决方案1】:

根据我的口味,在会话范围内使用当前用户是个好主意。

不过,如果不适合你,我可以提供更多替代方案。

将用户名作为视图参数传递

翻译成

<h:form>
    <h:inputText value="#{helloBean.name}"/>
    <h:commandButton value="Welcome Me - Action" action="#{helloBean.chkMe}"/>
</h:form>

public String chkMe() {
    return takeMeToAnotherPage("welcome");
}

public String takeMeToAnotherPage(String linkToGo) {
    return linkToGo + "?faces-redirect=true&username=" + name;
}

以及welcome.xhtml中的附加视图参数

<f:metadata>
    <f:viewParam name="username"/>
</f:metadata>

另一种选择是及时实例化另一个请求范围的bean并将信息传递给它

<h:form>
   <h:inputText value="#{helloBean.name}"/>
   <h:commandButton value="Welcome Me - Plain" action="welcome">
       <f:setPropertyActionListener value="#{helloBean.name}" target="#{welcomePageBean.username}"/>
   </h:commandButton>
</h:form>

@ManagedBean
@RequestScoped
WelcomePageBean {

    private String username;//+getter + setter
    //other fields associated with the welcome view

}

使用 Flash 对象

详情入口视图(片段),base.xhtml

<h:form>
    <h:outputText value="Enter user name for password reset: " />
    <h:inputText value="#{flash.username}" />
    <br/>
    <h:commandButton value="Send me a confirmation email" action="#{forgotBean.changePassword}" />
<h:form>

ForgotBeanbase.xhtml

@ManagedBean
@RequestScoped
public class ForgotBean {

    public ForgotBean() {   }

    public String changePassword() {
        //check user constraints and return failure outcome in case somthing is wrong
        //generate new password and persist it to the database
        //send a configmation e-mail
        return "successful-reset?faces-redirect=true";
    }

}

成功视图(片段),successful-reset.xhtml:

<h:outputText value="Password was reset for user #{receptorBean.username}, e-mail configmation sent." />
<br/>
<h:link value="View homepage" outcome="home" />

ReceptorBeansuccessful-reset.xhtml:

@ManagedBean
@RequestScoped
public class ReceptorBean {

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

    private String username;

    public ReceptorBean() {   }

    public String getUsername() {
        if(username == null) {
            String uname = (String)flash.get("username");
            flash.keep("inputText");
            username= uname;
        }
        return username;
    }

    public Flash getFlash() {
        return flash;
    }

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

}

【讨论】:

  • 我不能使用第二个选项,action="welcome" 因为 URL 给出了以前的 url 地址
  • &lt;f:metadata&gt; &lt;f:viewParam name="username"/&gt; &lt;/f:metadata&gt;,我在welcome.xhtml 中看不到任何内容
  • 并且使用视图参数,我在浏览器中看到 URL 为“welcome.xhtml?username=asdfasdf”意味着任何其他用户都知道用户名是什么,任何黑客都可以写一些其他用户名,这不是一个好主意...... .
  • 你为什么首先使用命令按钮? &lt;h:link&gt; 可以更好地执行导航。您不应该在帖子请求上导航。关于使用@SessionScoped bean 来保存实际上属于会话的数据,我不明白你为什么否认它。最后,如果您需要操作方法(并且不需要视图参数),为什么不能将第二个建议的解决方案与welcome?faces-redirect=true 一起使用,或者将这两个选项结合起来?
  • 我必须使用 commandButton ,因为我正在使用按钮(并且在 chkMe() 代码中我想执行一些操作)。第二个选项的问题是action="welcome"。我必须使用方法,因为我想执行一些操作。
【解决方案2】:

我想 faces-redirect=true 会进行 http 重定向,插入 http 转发。重定向由浏览器处理,浏览器发送一个新的 http 请求。由于您使用的是 RequestScoped Mbean,因此新请求将使用新的 MBean 呈现。 因此,请使用 SessionScoped Mbean 或不进行重定向导航。

【讨论】:

  • 我不能使用 sessionbean,因为它不能与 muti-tab 一起正常工作。我必须使用重定向,因为地址栏中的 URL 不正确。
  • 也许您应该将您的 Mbean 拆分为 sessionScoped 和 requestscoped mbean。
  • 您可以定义任意数量的托管 bean。为您的会话参数(例如用户名)定义 sessionscoped 托管 bean,并为您的请求参数(例如选项卡值)定义 requestscoped 托管 bean
  • 如何设置浏览器标签的值?
【解决方案3】:

因此,您的 bean 可能是 @RequestScoped。将其更改为 Session 范围的 bean。

【讨论】:

  • SessionBean 使用起来不是一个好主意(尤其是当我在许多选项卡中使用它时)
【解决方案4】:

让我们从 JSF 中抽象出来,从 HTTP 层面分析你的需求。

网址必须更改为welcome.xhtml

这意味着当点击按钮时,必须向服务器发送两个请求:

POST index.xhtml (with username parameter in the request body) - 提交用户输入到服务器

GET welcome.xhtml - 获取新页面

服务器处理GET welcome.xhtml请求时,有两种方式获取数据:

  • 从客户端的请求中获取数据(只有通过 GET 请求传递数据的方法是放到 URL 中)
  • 在服务器上可用(我们应该将其保存在“POST index.xhtml”处理中)

页面必须保持刷新

刷新只是对上次请求的重复。 这意味着我们正在重复GET welcome.xhtml 请求。 同样,我们有两种相同的方式来获取数据(从 url 和从服务器)。

网址不能包含数据(用户名)

这意味着无法从客户端的请求中检索数据。因此,获取数据的唯一方法是在“POST index.xhtml”处理期间首先将其存储在服务器上。

具有不同数据的多个选项卡

糟糕,目前唯一幸存下来的解决方案无法满足最后一个要求。 由于选项卡共享相同的浏览器会话(相同的 cookie 等),因此无法区分来自不同选项卡的请求。 所以来自不同标签的请求看起来完全一样,无法确定用户是刷新页面还是复制了url并打开了一个新标签。

结论

如果您提出严格的要求 - 就不可能实现您想要的(这不是 JSF 的限制,它是 HTTP 的工作方式)。所以你必须放宽要求。

删除多个选项卡支持 - 您可以使用 Session 范围。

Drop 存活刷新 - 您可以使用 Flash 范围。


最有趣的是放宽了在 url 中不传递数据的要求。

您可以做的最简单的事情就是按原样传递用户名参数。您可能会说这是一个安全风险,但我会说风险与在POST index.xhtml 请求中传递用户名几乎相同(只是传递参数的方式有所不同)。我看到的唯一额外的安全风险是有人可以通过用户的计算机并在浏览器的 url 栏中窥探用户名。

更高级的方法是加密用户名并在 URL 中传递加密值,并在处理welcome.xhtml 时对其进行解密。

如果我们进一步开发这种方法,我们将接近所谓的对话范围(查看 JBoss Seam 长时间运行的对话)。当您向 URL 添加无意义(从用户角度)参数时,该参数的值是一些标识符,用作服务器上数据映射的键。

对话范围的虚拟实现:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@ManagedBean
@SessionScoped
public class Bean implements Serializable {

    private int prevCid = 0;

    private Map<String, Object> conversationScope = new HashMap<String, Object>();

    public String getName() {
        return (String) getData();
    }

    public void setName(String name) {
        setData(name);
    }

    public String chkMe() {
        return takeMeToAnotherPage("welcome");
    }

    public String takeMeToAnotherPage(String linkToGo) {
        return linkToGo + "?cid=" + getCid() + "&faces-redirect=true";
    }

    private Object getData() {
        return conversationScope.get(getCid());
    }

    private void setData(Object o) {
        conversationScope.put(getCid(), o);
    }

    private String getCid() {
        HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
        String cid = (String) req.getAttribute("cid");

        if (cid == null) {
            cid = req.getParameter("cid");
            if (cid == null) {
              cid = "" + prevCid++;
            }
            req.setAttribute("cid", cid);
        }

        return cid;
    }
}

【讨论】:

    【解决方案5】:

    使用 Flash 对象的示例

    我实际上不明白什么不起作用。下面是 main-dependent 视图的工作示例,其中第一个视图上的命令按钮触发重定向到依赖视图并使用 JSF Flash 对象处理数据传输。在提供的答案中,第二个页面数据 (username) 在回发和页面刷新操作中都存在

    我将再次重新发布代码。

    主视图:

    <h:form>
        <h:outputText value="Enter your name: " />
        <h:inputText value="#{flash.username}" />
        <h:commandButton value="Reset my password" action="#{forgotBean.changePassword}" />
    </h:form>
    

    忘了豆子:

    @ManagedBean
    @RequestScoped
    public class ForgotBean {
    
        public ForgotBean() {   }
    
        public String changePassword() {
            return "/dependent?faces-redirect=true";
        }
    
    }
    

    依赖视图:

    <h:form>
       <h:outputText value="#{confirmBean.username}: your password has been changed and the confirmation has been sent to [get value from your bean]" />
       <h:commandButton value="Postback" />
    </h:form>
    

    确认 bean:

    @ManagedBean
    @RequestScoped
    public class ConfirmBean {
    
        @ManagedProperty("#{flash}")
        private Flash flash;
    
        private String username;
    
        public ReceivedBean() {   }
    
        public String getUsername() {
            if(username == null) {
                String uname = (String)flash.get("username");
                flash.keep("username");
                username = uname;
            }
            return username;
        }
    
        public Flash getFlash() {
            return flash;
        }
    
        public void setFlash(Flash flash) {
            this.flash = flash;
        }
    
    }
    

    或者,您也可以在ConfirmBean@PostConstruct 中进行预处理(验证用户名、收集电子邮件等数据等)。此外,您可以这样做@ViewScoped,这样就不会在回发时进行预处理。

    @PostConstruct 方法的启动示例:

    @PostConstruct
    public void init() {
        //without managed property flash object is also available via
        //FacesContext.getCurrentInstance().getExternalContext().getFlash()
        String name = flash.get("username");
        flash.keep("username");
        //do necessary validations
        //get necessary data from your service
        //handle wrong user input
        this.username = name;
        //set up other data of the bean
        //change setter and getter of the field username to 'ordinary'
    }
    

    使用会话范围 bean 的示例

    如果您希望 bean 在页面刷新后仍然存在(因此,@ViewScoped 失败),如果您想实现 Post-Redirect-Get(因此,&lt;f:setPropertyActionListener&gt; 失败),如果您想处理 基本上相同的数据,即几乎未定义,在不同的选项卡中(因此,Flash 失败),如果你想阻止有意义的获取请求(因此,&lt;f:viewParam&gt; 失败) ,那么我看到的唯一方法(留在 JSF 中)是使用 @SessionScoped @ManagedBean 将用户输入数据保存在集合中。这样,页面刷新回发重定向多标签有意义的视图参数 放宽限制并将在您的应用程序中启用。

    请注意,提供的代码不考虑任何异常处理/检查。而且,更重要和相关的是,作为映射中键的递增整数应该更好地替代随机值,例如 UUID

    视图(m 表示索引,d 表示欢迎):

    (m.xhtml):

    <h:body>
        <h:form>
            <h:inputText value="#{forgotBean2.username}" />
            <h:commandButton value="Change my password" action="#{forgotBean2.changePassword}" />
        </h:form>
    </h:body>
    

    (d.xhtml):

    <f:metadata>
        <f:viewParam name="id" required="true" />
    </f:metadata>
    <h:body>
        <h:form>
            <h:outputText value="#{confirmBean2.username}: your password has been changed" />
            <h:commandButton value="Postback" action ="#{confirmBean2.postbackAction}" />
        </h:form>
    </h:body>
    

    bean(ForgotBean2 - 用于m.xhtml 中的业务操作、ConfirmBean2 - 用于显示和(可能的)操作在d.xhtmlUserRequestsBean - 用于在会话中存储信息):

    (ForgotBean2):

    @ManagedBean
    @RequestScoped
    public class ForgotBean2 {
    
        @ManagedProperty("#{userRequestsBean}")
        private UserRequestsBean userRequestsBean;
    
        private String username;
    
        public ForgotBean2() {   }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public UserRequestsBean getUserRequestsBean() {
            return userRequestsBean;
        }
    
        public void setUserRequestsBean(UserRequestsBean userRequestsBean) {
            this.userRequestsBean = userRequestsBean;
        }
    
        public String changePassword() {
            //do business job
            Map<Integer, String> fMap = userRequestsBean.getRequests();
            int id = 0;
            if(fMap.containsValue(username)) {
                for(Map.Entry<Integer, String> entry : fMap.entrySet()) {
                    if(entry.getValue().equals(username)) {
                        id = entry.getKey();
                        break;
                    }
                }
            } else {
                if(fMap.isEmpty()) {
                    id = 1;
                } else {
                    id = (int)Collections.max(fMap.keySet()) + 1;
                }
                fMap.put(id, username);
            }
            return "/q15038451/d?faces-redirect=true&id=" + Integer.toString(id);
        }
    
    }
    

    (ConfirmBean2):

    @ManagedBean
    @ViewScoped
    public class ConfirmBean2 implements Serializable {
    
        @ManagedProperty("#{userRequestsBean}")
        private UserRequestsBean userRequestsBean;
    
        private Integer id;
    
        private String username;
    
        public ConfirmBean2() {   }
    
        @PostConstruct
        public void init() {
            if(id == null) {
                String vpid = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
                id = Integer.parseInt(vpid);
            }
            Map<Integer, String> fMap = userRequestsBean.getRequests();
            String uname = fMap.get(id);
            //do necessary validations
            //get necessary data from your service
            //handle wrong user input
            this.username = uname;
            //set up other data of the bean
        }
    
        public UserRequestsBean getUserRequestsBean() {
            return userRequestsBean;
        }
    
        public void setUserRequestsBean(UserRequestsBean userRequestsBean) {
            this.userRequestsBean = userRequestsBean;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String postbackAction() {
            return null;
        }
    
    }
    

    (UserRequestsBean):

    @ManagedBean
    @SessionScoped
    public class UserRequestsBean implements Serializable {
    
        private Map<Integer, String> requests = new HashMap<Integer, String>();
    
        public UserRequestsBean() {   }
    
        public Map<Integer, String> getRequests() {
            return requests;
        }
    
        public void setRequests(Map<Integer, String> requests) {
            this.requests = requests;
        }
    
    }
    

    如上所述,您可能希望生成UUIDs(提供唯一和随机值)而不是递增的Integers。

    【讨论】:

    • 问题仍然存在。当我使用两个选项卡并刷新第一个选项卡时,我看到第二个选项卡的数据(与会话 bean 相同)
    • 不应该存在的东西,所以应该省略)
    【解决方案6】:

    当您刷新页面时,您正在向服务器提交新请求。由于 HTTP 协议是无状态的,您可以通过将其添加到 URL 中来告诉服务器我是“user1”,因为该 URL 在选项卡中是唯一的。

    如果你不想在 URL 中添加参数,服务器将使用 session. 来维护两个请求之间的关系。然后您可以使用会话来存储变量等。

    在您的情况下,它不起作用,因为您不想在选项卡之间共享数据。 数据在选项卡之间共享的原因是会话 cookie 在选项卡上共享。

    您需要禁用 cookie 并使用 URL 重写来维护会话。

    http://docstore.mik.ua/orelly/java-ent/servlet/ch07_03.htm

    您使用的应用程序服务器应在 jsf 中维护 URL,并附加 sessionid,但是在重定向时您可能需要将会话 ID 附加到您的 URL。

        public String takeMeToAnotherPage(String linkToGo) {
               HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().
    getExternalContext().getRequest(); 
               return linkToGo + "?faces-redirect=true&jsessionid=" 
    + req.getSession().getId();
            }
    

    由于您的应用程序在多个选项卡上使用,您可以禁用会话 cookie 并使用 url 重写来维护会话。

    http://jf.omnis.ch/archives/2004/12/disabling-session-cookie-in-tomcat.html

    https://community.jboss.org/thread/141685

    另一种选择是使用对话范围,只要用户访问欢迎页面,您就可以在其中开始新对话。您的应用程序将在两个选项卡中维护两个不同的对话。您可以在此处了解更多信息,

    http://www.andygibson.net/blog/tutorial/cdi-conversations-part-2/

    【讨论】:

      【解决方案7】:

      当您刷新页面时,您正在向服务器提交新请求。由于 HTTP 协议是无状态的,因此您可以通过将其添加到 URL 中来告诉服务器我是“user1”,因为该 URL 在选项卡中是唯一的。

      如果您不想在 URL 中添加参数,服务器将使用 session. 维护两个请求之间的关系。然后您可以使用会话来存储变量等。

      在您的情况下,它不起作用,因为您不想在选项卡之间共享数据。数据在选项卡之间共享的原因是会话 cookie 在选项卡上共享。

      您需要禁用 cookie 并使用 URL 重写来维护会话。

      http://docstore.mik.ua/orelly/java-ent/servlet/ch07_03.htm

      您使用的应用程序服务器应在 jsf 中维护 URL,并附加 sessionid,但是在重定向时您可能需要将会话 ID 附加到您的 URL。

        public String takeMeToAnotherPage(String linkToGo) {
                 HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().
      getExternalContext().getRequest(); 
                 return linkToGo + "?faces-redirect=true&jsessionid=" 
      + req.getSession().getId();
              }
      

      由于您的应用程序在多个选项卡上使用,您可以禁用会话 cookie 并使用 url 重写来维护会话。

      http://jf.omnis.ch/archives/2004/12/disabling-session-cookie-in-tomcat.html

      https://community.jboss.org/thread/141685

      另一种选择是使用对话范围,您可以在用户访问欢迎页面时开始新对话。您的应用程序将在两个选项卡中维护两个不同的对话。您可以在此处了解更多信息,

      http://www.andygibson.net/blog/tutorial/cdi-conversations-part-2/

      【讨论】:

      • 删除了重复的答案。
      【解决方案8】:

      将此代码添加到您的索引页面的正文标记下方

      <t:saveState value="#{helloBean}" />
      

      t tag lib 使用

      <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
      

      并添加 tomahawk 库。

      如果您不知道保存状态或参数传递,请参考 this link

      这将帮助您通过基本步骤来传递价值。 jsf中的页面之间。

      【讨论】:

      • 但是我怎样才能使用从一页到另一页的价值呢?
      • 与您定义的 helloBean 中的相同对象,在您的情况下,在第二页中使用 #{helloBean.name}。它可能对你有用。
      • 请参考(stackoverflow.com/questions/2361616/…了解更多详情
      • 对不起new link
      猜你喜欢
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 2023-03-04
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      相关资源
      最近更新 更多