一. Managed Beans
JSF 使用 Bean 来达到逻辑层与表现层分离的目的,Bean 的管理集中在配置文件中,您只要修改配置文件,就可以修改 Bean 之间的相依关系。
1. Backing Beans
JSF使用JavaBeans来达到程序逻辑与试图分离的目的,在JSF中的Bean其角色是属于Backing Bean,又称之为Glue Bean,其作用是真正的业务逻辑Bean级UI组件之间搭起桥梁,在Backing Bean中会呼叫业务逻辑Bean处理使用者的请求,或者将业务逻辑处理结果放置其中,等待UI组件取出当中的值并显示给使用者。JSF将BEan 的管理集中在faces-config.xml中,如下例子:
....
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.UserBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
....
<managed-bean-class>设定所要使用的Bean类,<managed-bean-name>设定名称,可供我们在JSF页面上使用Expression Language来取得或设定Bean的属性,例如:
<h:inputText value="#{user.name}"/>
<managed-bean-scope>设定Bean的存活范围,你可以设定为request、session、与application,设定为request时,Bean的存活时间为请求阶段,设定为session则在使用者和应用程序交互开始,直到关闭浏览器或显示的结束会话为止(例如登出程序),设定为application时,则Bean会一直存活,直到应用程序关闭为止。
您还可以将存活范围设定为none,当设定为none时为在需要的时候生成一个新的Bean,例如您在一个method中想要生成一个临时的bean,就可以降至设定为none。
JSF页面上取得Bean 的属性,是使用JSF表示语言(Expression Language)。要注意的是,JSF表示语言是写成#{expression},而JSP表示语言是写成${expression},因为表示层可能使用JSP,所以必须区分,另外要注意的是,JSF标签上的属性设定时,只接受JSF表示语言。
2. Beans的配置和设定
JSF预定义会读取faces-config.xml中关于bean的定义,如果想要自行定义文件名称,我们是在web.xml文件中提供javax,faces.CONFIG_FILES参数,例如:
<web-app>
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>
...
</web-app>
定义文件可以有多个,中间以“,”区隔,例如:
/WEB-INF/navigation.xml,/WEB-INF/beans.xml
一个Bean最基本要定义的是Bean的名称、类与存活范围,例如:
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.UserBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
如果要在其他类中取得Bean对象,则可以先取得javax.faces.context.FacesContext,它代表了JSF目前的执行环境对象,接着尝试取得javax.faces.el.ValueBinding对象,从中取得指定的Bean对象,例如:
FacesContext context = FacesContext.getCurrentInstance();
ValueBinding binding = context.getApplication().createValueBinding("#{user}");
UserBean user = (UserBean) binding.getValue(context);
如果只是要尝试取得Bean的某个属性,则可以如下:
FacesContext context = FacesContext.getCurrentInstance();
ValueBinding binding=context.getApplication().createValueBinding("#{user.name}");
String name = (String) binding.getValue(context);
如果有必要在启始Bean时,自动设置属性的初始值,则可以如下的设定:
....
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.UserBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value>caterpillar</value>
</managed-property>
<managed-property>
<property-name>password</property-name>
<value>123456</value>
</managed-property>
</managed-bean>
当然您的属性不一定是字符串值,也许会是int、float、boolean等等类型,您可以设定<value>值时指定这个值的字符串名称,JSF会尝试进行转换,例如设定为true时,会尝试使用Boolean.ValueOf()方法转换为boolean的true,以下是一些可能进行的转换:
类型 | 转换 |
short、int、long、float、double、byte及相应的Wrapper类 | 尝试使用Wrapper的valueOf()进行转换,如果 没有设置,则设为0 |
boolean 或 Boolean | 尝试使用Boolean.valueOf()进行转换,如果没 有设置,则设为false |
char 或 Character | 取设置的第一个字符,如果没有设置,则设 为0 |
String 或 Object | 即设定的字符串值,如果没有设定,则为空 字符串new String("") |
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.UserBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>other</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.OtherBean
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>user</property-name>
<value>#{user}</value>
</managed-property>
</managed-bean>
在上面的设定中,在otherBean中的user属性,接受了一个UserBean类型的对象,我们设定为前一个名称为user的
UserBean对象。
<managed-bean>
<managed-bean-name>someBean</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.SomeBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>someProperty</property-name>
<list-entries>
<value-class>java.lang.Integer</value-class>
<value>1</value>
<value>2</value>
<value>3</value>
</list-entries>
</managed-property>
</managed-bean>
这是一个设定接受List类型的属性,我们使用<list-entries>标签指定将设定一个List对象,其中<value-class>指定将存入的List的类型,而<value>指定其值,如果是基本类型,则会尝试使用指定的<value-class>来作为Wrapper类。
<managed-bean>
<managed-bean-name>someBean</managed-bean-name>
<managed-bean-class>
onlyfun.caterpillar.SomeBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>someProperty</property-name>
<map-entries>
<value-class>java.lang.Integer</value-class>
<map-entry>
<key>someKey1</key>
<value>100</value>
</map-entry>
<map-entry>
<key>someKey2</key>
<value>200</value>
</map-entry>
</map-entries>
</managed-property>
</managed-bean>
由于Map对象是以key-value对的方式来存入的,所以我们在每一个<map-entry>中使用<key>与<value>标签来分别指定。
<managed-bean>
<description>
Special expense item types
</description>
<managed-bean-name>specialTypes</managed-bean-name>
<managed-bean-class>
java.util.TreeMap
</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<map-entries>
<value-class>java.lang.Integer</value-class>
<map-entry>
<key>Presentation Material</key>
<value>100</value>
</map-entry>
<map-entry>
<key>Software</key>
<value>101</value>
</map-entry>
<map-entry>
<key>Balloons</key>
<value>102</value>
</map-entry>
</map-entries>
</managed-bean>
而在范例中另一个设定List的例子如下:
<managed-bean>
<managed-bean-name>statusStrings</managed-bean-name>
<managed-bean-class>
java.util.ArrayList
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<list-entries>
<null-value />
<value>Open</value>
<value>Submitted</value>
<value>Accepted</value>
<value>Rejected</value>
</list-entries>
</managed-bean>