`
cuwkuhaihong
  • 浏览: 16871 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

托管 Bean 页面传值的使用方法和技巧(作者:紫蝶∏飛揚↗)

阅读更多

最 近开始学习JSF基础,发现比较重要的一点,就是如何用编程方式访问托管Bean。看了一些JSF的实例,不过大多都是用JSF1.1来实现的。虽然在 JSF1.2的环境中也可以很好运行,但是在编译的时候会看到降级的消息。这里找了一些资料总结一下JSF1.1和JSF1.2访问托管Bean的方法。

一、从JSF页面传递参数给托管Bean
虽然利用h:commandLink 和h:commandButton组件,可以通过action和actionListener来触发托管Bean中的方法,但是不能向这些方法中传递参 数。对于动态传递参数,不是不可以实现,这点可以通过使用f:attribute来实现。而且f:attribute也可以很好的和 actionListener联合使用。
例子:

<h:commandLink actionListener="#{myBean.action}">
        <f:attribute name="attrname1" value="attrvalue1" />
        <f:attribute name="attrname2" value="attrvalue2" />
        ...   
        <h:outputText value="Click here" />
    </h:commandLink>
    
    <h:commandButton value="Press here" actionListener="#{myBean.action}">
        <f:attribute name="attrname1" value="attrvalue1" />
        <f:attribute name="attrname2" value="attrvalue2" />
        ...
    </h:commandButton>

 这些属性可以通过父组件的getAttributes()方法取到,父组件可以通过传递给actionListener的ActionEvent实例取到。

public void action(ActionEvent event) {   
        String attrvalue1 = (String)  event.getComponent().getAttributes().get("attrname1");
        String attrvalue2 = (String) event.getComponent().getAttributes().get("attrname2");

}

 变量attrvalue1和attrvalue2包含从f:attribute set进来的值。
另一个欠文雅的方式就是通过f:param组件来传值,这个只是对h:commandLink起效。

<h:commandLink action="#{myBean.action}">
        <f:param name="paramname1" value="paramvalue1" />
        <f:param name="paramname2" value="paramvalue2" />
        ...
        <h:outputText value="Click here" />
    </h:commandLink>

 这些参数可以通过FacesContext的getRequestParameterMap()方法取到。通过下面的方法,可以获取任何写在command块中f:param的值。

 

public static String getFacesParamValue(String name) {   
        return (String) FacesContext.getCurrentInstance().getExternalContext().
               getRequestParameterMap().get(name);
}
 
//上面的方法可以用在任何Bean的方法中。举例


public void action() 
    ...{   
        String paramvalue1 = getFacesParamValue("paramname1");   
        String paramvalue2 = getFacesParamValue("paramname2");   
        ...
    }
/*
变量paramvalue1和paramvalue2包含从f:param set进来的值。
不过要注意,属性的名字要唯一,而且不能用其他组件的属性名,比如:"id", "name", "value","binding",
 "rendered",等。

二、从JSF页面传递组件属性到托管Bean
f:attribute组件也可以用来访问,任何绑定在托管Bean的UI组件的属性。这些属性值可以通过父组件的
getAttributes()来获得。因为不能以方法参数的方式传值给托管Bean绑定的UI组件的getter和setter方法,
这时f:attribute就会非常有用。这里有个 UI组件绑定到托管Bean的基础例子
*/

<h:outputText binding="#{myBean.myText}" value="#{myBean.myTextValue}">
        <f:attribute name="attributename" value="attributevalue" />
    </h:outputText>

 


托管Bean代码:

import javax.faces.component.html.HtmlOutputText;
public class MyBean 
{   
    private HtmlOutputText myText; 
    
    public HtmlOutputText getMyText() 
   {   
        return myText;  
    }   
    
    public String getMyTextValue() 
    {       
        return (String) myText.getAttributes().get("attributename");   
    }
    
    public void setMyText(HtmlOutputText myText) 
   {       
        this.myText = myText;
    }
}
/*
三、在请求之间传递对象(Passing objects from request to request)
如果有一个request范围内的托管Bean,在下一个请求中想要重用这个bean的属性,参数,
或者对象,但是不想一遍又一遍的初始化这个Bean。可以用h:inputhidden来解决这个问题。
这里有个简单的例子:
*/

<h:form>   

        <h:inputHidden value="#{myBean.value}" />
  
    </h:form>

另一种方法就是用SessionMap来保存那些需要保存在session中的值。


public class MyBean 
{   
    public Object getMyValue() 
    {       
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.get("MyBeanMyValue"); 
    }   
    
    public void setMyValue(Object myValue) 
    {       
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.put("MyBeanMyValue", myValue);
    }  
      
    // This might be useful.   
    private void resetSessionValue(Object myKey) 
    {       
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(myKey);
    }
}
/*
四、在托管Bean之间通信
实践时会有多个托管Bean。如果设计需要,可以利用getSessionMap()在托管Bean之间通信。
一个例子,有两个托管Bean:
*/

<managed-bean>
        <managed-bean-name>myBean1</managed-bean-name>
        <managed-bean-class>mypackage.MyBean1</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>myBean2</managed-bean-name>
        <managed-bean-class>mypackage.MyBean2</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
/*
托管Bean myBean1和myBean2是支撑Bean MyBean1.java和MyBean2.java的实例,
它们可以通过JSF页面来访问。不管它们的managed-bean-scope是 request还是session。
如果managed-bean-scope被设置成session,在整个session范围内可以使用同一个 Bean的实例;
如果managed-bean-scope被设置成request,那么每个request(form action)每次会创建一个Bean的实例。

用下面的方法,可以为每个托管Bean set和get static的参数。可以把它写成protected方法,放在一个超类中,
让每个托管Bean继承,这会非常有用,或者写入一个Util类中,自己选择。

*/


public class MySuperBean 
{   
    protected static Object getSessionValue(Object myKey) 
    {       
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.get(myKey);
    }   
    
    protected static void setSessionValue(Object myKey, Object myValue) {       
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().
put(myKey, myValue);
    }
}

public class MyBean1 extends MySuperBean {   
    public void myMethod() {       
        String myValue = "value1";       
        setSessionValue("MyBean1MyValue", myValue); 
    }
}
public class MyBean2 extends MySuperBean {   
    public void myMethod(){       
        String myValue = (String) getSessionValue("MyBean1MyValue");
    }
}
/**
五、在托管Bean中访问另一个托管Bean
如果有很多托管Bean,想要从其中一个托管Bean访问其他的托管Bean,这里有六中方法。
可以使用:
  1)getVariableResolver
  2)createValueBinding
  3)getELResolver (since JSF 1.2)
  4)createValueExpression (since JSF 1.2)
  5)getRequestMap
  6)getSessionMap.
举例:假设有两个托管Bean
*/

<managed-bean>
    <managed-bean-name>myBean1</managed-bean-name>
    <managed-bean-class>mypackage.MyBean1</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>myBean2</managed-bean-name>
    <managed-bean-class>mypackage.MyBean2</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

//托管Bean myBean1和myBean2是支撑Bean MyBean1.java和//MyBean2.java的实例,
//它们可以通过JSF页面来访问。不管它们的managed-//bean-scope是request还是session。
//只是要注意的是,getRequestMap在托管Bean被设置成request的时候使//用,getSessionMap
//在托管Bean被设置成session的时候使用。


<h:form>   
    <h:commandButton action="#{myBean1.action1}" value="action1" />
    <h:commandButton action="#{myBean1.action2}" value="action2" />
    <h:commandButton action="#{myBean1.action3}" value="action3" />
    <h:commandButton action="#{myBean1.action4}" value="action4" />
    <h:commandButton action="#{myBean1.action5}" value="action5" />
    <h:commandButton action="#{myBean1.action6}" value="action6" />
    <h:outputText binding="#{myBean2.text}" />
</h:form>

MyBean1.java:

package mypackage;
import javax.faces.context.FacesContext;
public class MyBean1 {    
    // Using VariableResolver. NOTE: this is deprecated since JSF 1.2!   
    public void action1() {       
        FacesContext context = FacesContext.getCurrentInstance();       
        MyBean2 myBean2 = (MyBean2) context.getApplication()
.getVariableResolver().resolveVariable(context, "myBean2");
        myBean2.getText().setValue("action1");   
    }   
    
    // Using ValueBinding. NOTE: this is deprecated since JSF 1.2!   
    public void action2() 
    {       
        FacesContext context = FacesContext.getCurrentInstance(); 
        MyBean2 myBean2 = (MyBean2) context.getApplication()
.createValueBinding("#{myBean2}").getValue(context);       
        myBean2.getText().setValue("action2");   
    }   
    
    // Using ELResolver. NOTE: this is implemented since JSF 1.2!  
    public void action3() 
    ...{       
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getELContext().getELResolver()
.getValue(context.getELContext(), null, "myBean2");
        myBean2.getText().setValue("action3");
    }   
    
    // Using ValueExpression. NOTE: this is implemented since JSF 1.2!   
    public void action4() 
    {       
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication().getExpressionFactory()
.createValueExpression(context.getELContext(), "#{myBean2}", MyBean2.class)
.getValue(context.getELContext());
        myBean2.getText().setValue("action4");   
    }  
    
    // Using RequestMap. NOTE: myBean2 should be request scoped!   
    public void action5() 
    {       
        Object object = FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
.get("myBean2");
        // This only works if myBean2 is request scoped.       
        if (object != null) 
        ...{           
            MyBean2 myBean2 = (MyBean2) object;
            myBean2.getText().setValue("action5");       
        }   
    }   
    
    // Using SessionMap. NOTE: myBean2 should be session scoped!   
    public void action6() 
    {       
        Object object =  FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.get("myBean2");
        // This only works if myBean2 is session scoped.       
        if (object != null) 
        {         
            MyBean2 myBean2 = (MyBean2) object;
            myBean2.getText().setValue("action6"); 
        }   
    }

}

MyBean2.java:

package mypackage;
import javax.faces.component.html.HtmlOutputText;
public class MyBean2 {   
    private HtmlOutputText text;   
    
    public HtmlOutputText getText() 
    {       
        return text;   
    }   
    
    public void setText(HtmlOutputText text) 
    {       
        this.text = text;   
    }
}
 
分享到:
评论

相关推荐

    第9章 JSF的托管Bean和国际化课件及源程序

    总结来说,本章内容将涵盖JSF托管Bean的基础知识,包括如何创建、声明和使用Bean,以及如何在Bean中实现业务逻辑。同时,还会讲解如何实现国际化,包括资源包的创建和使用,以及在JSF应用中显示本地化文本的方法。...

    std::string、char*、const char*转托管byte数组或托管字符串String

    std::string、char*、const char*...std::string、char*、const char*可以使用不同的方法转换为托管的byte数组或字符串,但它们的转换方法都需要使用Marshal::Copy函数和System::Text::Encoding::UTF8-&gt;GetString函数。

    GitHub托管HTML页面

    设置远程仓库是指将我们的仓库地址和名字添加到 GitHub 托管的仓库中。在这里,我们可以点击“Settings”按钮,并添加我们的仓库地址和名字。添加成功后,我们可以点击“Save”按钮,关闭设置页面。 六、访问页面 ...

    非托管代码回调方法的实现

    非托管代码回调方法的实现是将托管代码与非托管代码(如C++或原生DLL)集成的关键技术。在.NET框架中,托管代码是由CLR(Common Language Runtime)管理的,而非托管代码则不受其控制。当需要从非托管代码调用托管...

    关于托管C++和非托管C++各种字符串类型的转换

    本文将详细介绍托管C++(Managed C++)与非托管C++(Unmanaged C++)之间各种字符串类型转换的方法与技巧。虽然从表面上看这些转换操作似乎很简单,但实际上涉及到的技术细节和背景知识相当丰富。通过本文的学习,...

    超详细解析托管代码与非托管代码以及dll调用.zip_托管代码_非托管

    托管代码与非托管代码是编程领域中的两个重要概念,它们主要与.NET框架和C++等语言的使用密切相关。本文将深入探讨这两个概念,以及DLL动态链接库调用...理解这些概念和技巧,对于提升软件开发效率和质量具有重要意义。

    托管 vs 非托管

    托管与非托管代码是编程领域中的两个重要概念,主要涉及.NET框架和C++等语言的使用。这篇文章将深入探讨这两者的差异,以及它们在实际开发中的应用。 托管代码(Managed Code)是指能够在.NET Framework的公共语言...

    JavaServer Faces完全参考手册(JSF:Complete Reference)

    - **直接声明List和Map为托管bean**:讨论了如何直接使用List和Map作为托管bean。 - **托管bean的相互依赖**:探讨了托管bean之间的相互依赖关系。 - **用EL设置托管属性**:解释了如何使用表达式语言(EL)来设置...

    非托管C++调用C#的dll

    然而,CLR VIA C#提供了一种非托管C++直接调用的方法,该方法可以在非托管代码中手动启动CLR加载应用程序域来运行托管的dll,从而调用其中的方法。 知识点1:C++调用C#编写的dll的必要性 在实际开发中,C++和C#是...

    Axis传值和复杂对象

    【标题】"Axis传值和复杂对象"涉及的是在Web服务开发中,使用Apache Axis框架进行数据传递,特别是处理复杂对象的场景。Apache Axis是一个开源的Web服务工具包,它允许开发者创建、部署和调用Web服务。在这个场景中...

    托管代码机制(很使用)

    ### 托管代码机制 #### 一、托管代码机制简介 托管代码机制是现代软件开发中的一个重要概念,尤其是在.NET框架及后续.NET Core/.NET 5+版本中扮演着核心角色。托管代码指的是那些运行在.NET运行时环境(Common ...

    GitHub是一个面向开源及私有软件项目的托管平台,它使用Git作为唯一的版本库格式进行托管 以下是对GitHub的详细介绍:

    代码托管:GitHub允许用户上传、存储和管理自己的代码库,并提供版本控制功能。 社区协作:用户可以关注其他用户或项目,参与讨论、提交问题(Issue)和拉取请求(Pull Request),促进项目的发展和代码的改进。 ...

    JSF2.0_the_full_reference

    - **表达式语言(EL)**:JSF的表达式语言允许在页面中引用托管Bean和其他对象,简化了数据绑定过程。 - **核心标签库(Core Tags)**:提供了一组标准的JSF组件,如按钮、文本输入框、单选按钮等,用于快速构建用户...

    使用托管C++粘合C#和C++代码.pdf

    mgClass类的属性 getter 和 setter 方法中,我们使用了托管C++的语法,例如使用gcnew关键字来创建托管字符串对象,并使用PtrToStringChars函数来将托管字符串对象转换为非托管字符串。 在使用托管C++将C#和C++代码...

    非托管C++委托实现

    10. **事件模型**:非托管C++中没有内置的事件模型,但可以通过委托类实现类似的功能,例如添加订阅和取消订阅的方法,以支持事件的发布和接收。 通过上述知识点的综合运用,非托管C++环境下的委托实现可以提供一种...

    Fragment的传值问题

    本文总结了Fragment在不同情况下的传值方法,包括不同Activity下的Fragment的传值,相同Acitvity托管下不同Fragment的传值。同一界面不同Fragment传值并实时变化的情况。了解了这些,基本上Fragment的通信就不会再有...

    c#调用非托管dll

    C# 调用非托管 DLL 是指在 C# 程序中使用非托管动态链接库(DLL)的方法。非托管 DLL 是指使用 C 或 C++ 编写的动态链接库,而不是使用 .NET 框架编写的 DLL。为了在 C# 中使用非托管 DLL,我们需要使用 DllImport ...

    托管平台与非托管的互操作

    【托管平台与非托管的互操作】是指在编程中,如何让使用托管代码(如C#)的应用程序与非托管代码(如C++)进行通信和数据交换。COM(Component Object Model)组件是这种互操作性的一个关键工具,因为它们可以被不同...

Global site tag (gtag.js) - Google Analytics