`
ruilin521314
  • 浏览: 902279 次
文章分类
社区版块
存档分类
最新评论

托管 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:commandLinkactionListener="#{myBean.action}">
<f:attributename="attrname1"value="attrvalue1"/>
<f:attributename="attrname2"value="attrvalue2"/>
...
<h:outputTextvalue="Clickhere"/>
</h:commandLink>

<h:commandButtonvalue="Presshere"actionListener="#{myBean.action}">
<f:attributename="attrname1"value="attrvalue1"/>
<f:attributename="attrname2"value="attrvalue2"/>
...
</h:commandButton>

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



publicvoidaction(ActionEventevent)
...{
Stringattrvalue1
=(String)event.getComponent().getAttributes().get("attrname1");
Stringattrvalue2
=(String)event.getComponent().getAttributes().get("attrname2");
...
}

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



<h:commandLinkaction="#{myBean.action}">
<f:paramname="paramname1"value="paramvalue1"/>
<f:paramname="paramname2"value="paramvalue2"/>
...
<h:outputTextvalue="Clickhere"/>
</h:commandLink>

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



publicstaticStringgetFacesParamValue(Stringname)
...{
return(String)FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
}

上面的方法可以用在任何Bean的方法中。举例



publicvoidaction()
...{
Stringparamvalue1
=getFacesParamValue("paramname1");
Stringparamvalue2
=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:outputTextbinding="#{myBean.myText}"value="#{myBean.myTextValue}">
<f:attributename="attributename"value="attributevalue"/>
</h:outputText>



托管Bean代码:

importjavax.faces.component.html.HtmlOutputText;
publicclassMyBean
...{
privateHtmlOutputTextmyText;

publicHtmlOutputTextgetMyText()
...{
returnmyText;
}


publicStringgetMyTextValue()
...{
return(String)myText.getAttributes().get("attributename");
}


publicvoidsetMyText(HtmlOutputTextmyText)
...{
this.myText=myText;
}

}

三、在请求之间传递对象(Passing objects from request to request)
如果有一个request范围内的托管Bean,在下一个请求中想要重用这个bean的属性,参数,或者对象,但是不想一遍又一遍的初始化这个Bean。可以用h:inputhidden来解决这个问题。这里有个简单的例子:



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

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



publicclassMyBean
...{
publicObjectgetMyValue()
...{
returnFacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("MyBeanMyValue");
}


publicvoidsetMyValue(ObjectmyValue)
...{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
"MyBeanMyValue",myValue);
}


//Thismightbeuseful.
privatevoidresetSessionValue(ObjectmyKey)
...{
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类中,自己选择。



publicclassMySuperBean
...{
protectedstaticObjectgetSessionValue(ObjectmyKey)
...{
returnFacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(myKey);
}


protectedstaticvoidsetSessionValue(ObjectmyKey,ObjectmyValue)
...{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(myKey,myValue);
}

}


publicclassMyBean1extendsMySuperBean
...{
publicvoidmyMethod()
...{
StringmyValue
="value1";
setSessionValue(
"MyBean1MyValue",myValue);
...
}

}

publicclassMyBean2extendsMySuperBean
...{
publicvoidmyMethod()
...{
StringmyValue
=(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:commandButtonaction="#{myBean1.action1}"value="action1"/>
<h:commandButtonaction="#{myBean1.action2}"value="action2"/>
<h:commandButtonaction="#{myBean1.action3}"value="action3"/>
<h:commandButtonaction="#{myBean1.action4}"value="action4"/>
<h:commandButtonaction="#{myBean1.action5}"value="action5"/>
<h:commandButtonaction="#{myBean1.action6}"value="action6"/>
<h:outputTextbinding="#{myBean2.text}"/>
</h:form>

MyBean1.java:

packagemypackage;
importjavax.faces.context.FacesContext;
publicclassMyBean1
...{
//UsingVariableResolver.NOTE:thisisdeprecatedsinceJSF1.2!
publicvoidaction1()
...{
FacesContextcontext
=FacesContext.getCurrentInstance();
MyBean2myBean2
=(MyBean2)context.getApplication().getVariableResolver().resolveVariable(context,"myBean2");
myBean2.getText().setValue(
"action1");
}


//UsingValueBinding.NOTE:thisisdeprecatedsinceJSF1.2!
publicvoidaction2()
...{
FacesContextcontext
=FacesContext.getCurrentInstance();
MyBean2myBean2
=(MyBean2)context.getApplication().createValueBinding("#{myBean2}").getValue(context);
myBean2.getText().setValue(
"action2");
}


//UsingELResolver.NOTE:thisisimplementedsinceJSF1.2!
publicvoidaction3()
...{
FacesContextcontext
=FacesContext.getCurrentInstance();
MyBean2myBean2
=(MyBean2)context.getELContext().getELResolver().getValue(context.getELContext(),null,"myBean2");
myBean2.getText().setValue(
"action3");
}


//UsingValueExpression.NOTE:thisisimplementedsinceJSF1.2!
publicvoidaction4()
...{
FacesContextcontext
=FacesContext.getCurrentInstance();
MyBean2myBean2
=(MyBean2)context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(),"#{myBean2}",MyBean2.class).getValue(context.getELContext());
myBean2.getText().setValue(
"action4");
}


//UsingRequestMap.NOTE:myBean2shouldberequestscoped!
publicvoidaction5()
...{
Objectobject
=FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("myBean2");
//ThisonlyworksifmyBean2isrequestscoped.
if(object!=null)
...{
MyBean2myBean2
=(MyBean2)object;
myBean2.getText().setValue(
"action5");
}

}


//UsingSessionMap.NOTE:myBean2shouldbesessionscoped!
publicvoidaction6()
...{
Objectobject
=FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("myBean2");
//ThisonlyworksifmyBean2issessionscoped.
if(object!=null)
...{
MyBean2myBean2
=(MyBean2)object;
myBean2.getText().setValue(
"action6");
}

}


}


MyBean2.java:

packagemypackage;
importjavax.faces.component.html.HtmlOutputText;
publicclassMyBean2
...{
privateHtmlOutputTexttext;

publicHtmlOutputTextgetText()
...{
returntext;
}


publicvoidsetText(HtmlOutputTexttext)
...{
this.text=text;
}

}

原文章地址:http://www.blogjava.net/algz/articles/193459.html

分享到:
评论

相关推荐

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

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

    GitHub托管HTML页面

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

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

    本文将深入探讨如何在非托管API中实现回调方法,以确保跨语言和跨环境的交互顺畅。 首先,理解非托管回调的原理。回调本质上是将一个函数指针作为参数传递给另一个函数,这样被调用的函数可以在适当的时候通过这个...

    Axis传值和复杂对象

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

    托管 vs 非托管

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

    Fragment的传值问题

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

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

    4. 使用ExecuteInDefaultAppDomain函数来调用托管的dll中的方法。 知识点5:C#编写的dll的签名 C#编写的dll需要具有特定的签名,以便C++代码可以正确地调用它。该签名需要满足以下要求: * 方法必须是静态的。 * ...

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

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

    托管代码机制(很使用)

    综上所述,托管代码机制不仅极大地提升了应用程序的性能和安全性,而且还简化了开发过程,使开发者能够更专注于业务逻辑而非底层技术细节。对于希望充分利用.NET框架的强大功能的开发者来说,了解并掌握托管代码机制...

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

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

    非托管C++委托实现

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

    皮托管使用说明 皮托管使用说明

    它主要分为两种类型:标准型(L型)皮托管和S型皮托管,每种都有其特定的应用场景和使用方法。 L型皮托管适用于测量薄壁管道和烟道内较为清洁的气体流速,其工作原理是通过全压管口接收气流的总压力,而静压管口则...

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

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

    非托管字符串和托管字符串的转换

    2. **IntPtr 和 Marshal.PtrToStringAnsi/UTF8/UniCode**:可以将托管字符串的引用转换为`IntPtr`,然后使用`Marshal.PtrToStringAnsi/UTF8/Unicode`方法获取非托管字符串。这种方法适用于已知字符串编码的情况。 3...

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

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

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

    托管C++是微软.NET框架提供的一种特性,它允许开发者在.NET环境中使用C++语言,同时能够无缝地与C#和其他.NET语言交互。这种技术的核心在于,托管C++编译后的代码能够理解并遵循.NET框架的规则,比如垃圾回收、类型...

    非托管动态库调用

    `LibWrapper` 类包含了 `GetSystemTime` 方法的导入,使用 `DllImportAttribute` 指定 DLL 和入口点。这样,就可以在托管代码中安全地调用 `GetSystemTime` 函数,获取系统的当前时间。 非托管动态库调用在 .NET 中...

    c#调用非托管dll

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

Global site tag (gtag.js) - Google Analytics