1. 前言
这个是对于以前JSF学习的一点点补充,因为笔者前些日子使用Struts2使用的太多了。后来发现JSF生疏很多了,那么写一下这次关于JSF的使用补充的笔记,留给自己以后使用的时候参考用。
2. 流程转向
如果配置了以下流程
<navigation-rule> <from-view-id>addUser.xhtml</from-view-id> <navigation-case> <from-outcome>addUserSuccess</from-outcome> <to-view-id>login.xhtml</to-view-id> <redirect /> </navigation-case> <navigation-case> <from-outcome>addUserError</from-outcome> <to-view-id>addUser.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>serchUserMoneySuccess</from-outcome> <to-view-id>userMoney.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>serchUserInfoSuccess</from-outcome> <to-view-id>userMoney.xhtml</to-view-id> </navigation-case> </navigation-rule>
翻译过来就是所有以addUser.xhtml为入口的页面的动作,经过托管Bean的处理后会有4种可能的出口,分别是:addUserSuccess、addUserError、serchUserMoneySuccess、serchUserInfoSuccess。
那么像以下这种配置
<navigation-rule> <navigation-case> <from-action>#{adminAction.logout}</from-action> <from-outcome>logout</from-outcome> <to-view-id>login.xhtml</to-view-id> </navigation-case> <navigation-case> <from-action>#{adminAction.listException}</from-action> <from-outcome>listExceptionSuccess</from-outcome> <to-view-id>listExceptionSuccess.xhtml</to-view-id> </navigation-case> </navigation-rule>
则翻译过来就是流程仅仅关注托管Bean的动作,触发了托管Bean的相关方法的时候,对方法做一个结果字符串的转向。如果发现在托管Bean中发生了错误,要么是直接在页面上报出Exception,要么就是捕获异常后提示错误信息给输入视图。其中adminAction是有效的托管Bean。Logout和listException是托管Bean的方法。2种配置都是对流程的一种描述,前者更偏向于表单提交、后者更偏向于组件动作相应。
4. 界面参数传递
在Struts2中将页面的参数传递到Action中是一件十分简单的事情。而JSF就得在托管Bean的配置文件配置一下。比如现在需要界面传递一个userId甚至是adminDTO给托管Bean——adminAction,就得如下配置
<managed-bean> <managed-bean-name>adminAction</managed-bean-name> <managed-bean-class>web.action.AdminAction</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <!--从页面上传过来的参数--> <managed-property> <property-name>adminDTO</property-name> <value>#{adminDTO}</value> </managed-property> <managed-property> <property-name>userId</property-name> <value>#{param.userId}</value> </managed-property> <managed-property> <property-name>dealInfoId</property-name> <value>#{param.dealInfoId}</value> </managed-property> <managed-property> <property-name>exceptionId</property-name> <value>#{param.exceptionId}</value> </managed-property> <managed-property> <property-name>page</property-name> <value>#{param.page}</value> </managed-property> </managed-bean>
4. 使用资源文件国际化
国际化这次分为2个部分
1):JSF自身消息的国际化
因为JSF自身的消息提示默认是英文的,所以需要自己建立一个消息提示的资源文件,messages_zh_CN.properties文件如下
javax.faces.validator.NOT_IN_RANGE={2}\u6307\u5B9A\u5C5E\u6027\u503C\u4E0D\u5728[0}\uFF0C{1}]\u8303\u56F4\u5185 javax.faces.validator.NOT_IN_RANGE_detail={2}\u503C\u5FC5\u987B\u4ECB\u4E8E[{0}\uFF0C{1}]\u4E4B\u95F4 javax.faces.validator.DoubleRangeValidator.LIMIT={0}\u8D85\u8FC7\u4E86double\u7C7B\u578B\u7684\u6781\u9650 javax.faces.validator.DoubleRangeValidator.MAXIMUM={1}\u5927\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5927\u503C\u201C{0}\u201D javax.faces.validator.DoubleRangeValidator.MINIMUM={1}\u5C0F\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5C0F\u503C\u201C{0}\u201D javax.faces.validator.DoubleRangeValidator.TYPE={0}\u4E0D\u662F\u6709\u6548\u7684double\u7C7B\u578B javax.faces.validator.LengthValidator.LIMIT={0}\u8D85\u8FC7\u4E86\u5B57\u7B26\u6781\u9650 javax.faces.validator.LengthValidator.MAXIMUM={1}\u957F\u5EA6\u5927\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5927\u503C\u201C{0}\u201D javax.faces.validator.LengthValidator.MINIMUM={1}\u957F\u5EA6\u5C0F\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5C0F\u503C\u201C{0}\u201D javax.faces.component.UIInput.CONVERSION=\u6570\u636E\u8F6C\u6362\u9519\u8BEF javax.faces.component.UIInput.REQUIRED={0}\u662F\u5FC5\u586B\u9879 javax.faces.component.UISelectOne.INVALID={0}\u9009\u62E9\u5185\u5BB9\u65E0\u6548 javax.faces.component.UISelectMany.INVALID={0}\u9009\u62E9\u5185\u5BB9\u65E0\u6548 javax.faces.validator.RequiredValidator.FAILED={0}\u662F\u5FC5\u586B\u9879. javax.faces.validator.LongRangeValidator.LIMIT={0}\u8D85\u8FC7\u4E86long\u7C7B\u578B\u7684\u6781\u9650 javax.faces.validator.LongRangeValidator.MAXIMUM={1}\u5927\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5927\u503C\u201C{0}\u201D javax.faces.validator.LongRangeValidator.MINIMUM={1}\u5C0F\u4E8E\u4E86\u5141\u8BB8\u7684\u6700\u5C0F\u503C\u201C{0}\u201D javax.faces.validator.LongRangeValidator.TYPE={0}\u4E0D\u662F\u6709\u6548\u7684long\u7C7B\u578B
之后在JSF的配置文件中配置如下
<application> <message-bundle>messages</message-bundle> <locale-config> <default-locale>zh_CN</default-locale> <!--默认资源文件--> <supported-locale>en</supported-locale> <!--支持的资源文件--> <supported-locale>en_IE</supported-locale> <!--支持的资源文件--> </locale-config> </application> <application> <locale-config> <default-locale>zh_CN</default-locale> </locale-config> <!-- 配置Facelets的支持 --> <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> </application>
2:)其他信息输出的国际化文件
首先建立一个国际化文件message.properties,内容如下
loginButton=\u767B\u5F55 addUser=\u6DFB\u52A0\u7528\u6237 updateUserMoney=\u5145\u503C transferMoney=\u8F6C\u8D26
在页面加载的时候可以如下
<f:loadBundle basename="message" var="msg" />
代表加载资源文件,之后使用msg就可以使用资源文件中的信息了。代码如下
<h:commandButton action="#{userAction.addUser}" styleClass="btn-submit" value="#{msg.addUser}" />
5. h:commandLink与h:outputLink的区别
h:commandLink一般是触发托管Bean的某些方法的时候用到的。
<h:commandLink action="#{adminAction.deleteDeal}" value="【刪除】"> <f:param name="dealInfoId" value="#{dealInfoDTOListVar.id}" /> </h:commandLink>
而h:outputLink仅仅是连接到某一个JSP或者XHTML页面的。
<h:outputLink value="#{ctxPath}/mangerTeam/addTeam.faces"> <h:outputText value="【添加俱乐部】" /> </h:outputLink>
需要说明的是h:commandLink中的action中的表达式只能是针对于一个托管Bean的合法方法。不能是一个变量值或者是一个像h:outputLink中的URL连接。
6. 获取JSF项目名称
通过如下方式可获取项目名称
<c:set var="ctxPath" value="#{facesContext.externalContext.requestContextPath}" />
7. 视图下有特殊类型变量
比如一个页面的表单有个Double类型的变量需要转型,那么应该如此
1:先通过一个托管Bean的方法转向某个含有需要变量转型的页面。
/** * 准备转账 * * @return */ public String preTransferMoney() { return "preTransferMoney"; }
在流程配置文件配置流程如下
<navigation-rule> <navigation-case> <from-action>#{userAction.preTransferMoney}</from-action> <from-outcome>preTransferMoney</from-outcome> <to-view-id>preTransferMoney.xhtml</to-view-id> </navigation-case> <navigation-case> <from-action>#{userAction.transferMoney}</from-action> <from-outcome>serchUserMoneySuccess</from-outcome> <to-view-id>userMoney.xhtml</to-view-id> </navigation-case> </navigation-rule>
在preTransferMoney.xhtml中的表单需要转型配置如下
<tr> <td>转账金額: </td> <td><h:inputText id="money" value="#{userAction.money}" required="true"> <f:converter converterId="javax.faces.Double" /> </h:inputText>元 </td> </tr>
这样提交后就没转型错误的问题了~
8. 逻辑表达式
在JSF的页面中遍历实体、逻辑判断这些操作都需要借助于JSTL和EL表达式,因为JSF1.2标准自身并没有提供这种逻辑标签。不像Struts2,<s:if>可以做逻辑判断。所以它必须借助EL表达式和JSTL做逻辑处理。