1、页面导航问题:
<h:commandButton label="Login" action="login"/>
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/welcome.jsp</to-view-id>
</navigation-case>
</navigation-rule>
注意:这里的view-id必须以"/"开始,扩展名为.jsp
2008-6-11
2、导航中的<redirect />作用
<navigation-rule> <from-view-id>/archives/admin/archivesAudit.jsp</from-view-id> <navigation-case> <from-outcome>auditFinish</from-outcome> <to-view-id>/archives/admin/archivesBrowse.jsp</to-view-id> <redirect /> </navigation-case> </navigation-rule>
如果不选择此项,从当前页面跳转到另一个页面后,地址栏保留的是请求的URL,server只是做了一个转发的动作;如果选择“重定向”,则地址栏里保留的 是被请求的URL,server会重新发送一个被请求的URL。
2008-6-11
3、注意点:如果没有导航规则来匹配一个给定的action,那么当前页面将简单的重新显示一下。如果一个action method返回null,那么将重新显示页面本身。
4、在受管bean中向页面发送消息
FacesMessage message=new FacesMessage(FacesMessage.SEVERITY_ERROR,getMes(FacesContext.getCurrentInstance(),"USERNAME_REPEAT_MESSAGE"),null);
FacesContext.getCurrentInstance().addMessage(null, message);
getMes()方法:
private String getMes(FacesContext fc,String key) { String str=null; ResourceBundle rb=ResourceBundle.getBundle("com.xgtimes.CustomMessages", fc.getViewRoot().getLocale()); str=rb.getString(key); return str; }
重点就是,直接通过FacesContext类方法getCurrentInstance()获取当前上下文对象。
5、判断用户是否已经登录
登录成功后设置用户session
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("userId",userId);
在后台可以通过
if(FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userId") != null)
来判断是否登录;
在页面则可通过
facesContext.externalContext.sessionMap['userId'] != null
来判断是否登录;
exp(页面判断):
<h:commandLink value="Login" action="#{loginBean.loginAction}" rendered="#{facesContext.externalContext.sessionMap['userId'] == null}"/>
<h:commandLink value="userName:[Logout]" action="#{loginBean.loginAction}" rendered="#{facesContext.externalContext.sessionMap['userId'] != null}"/>
或者可以直接用jsp提供的方法来判断也行:
<%if(session.getAttribute("userId") != null){%>
<h:commandLink value="userName:[Logout]" action="#{loginBean.loginAction}"/>
<%}else{%>
<h:commandLink value="Login" action="#{loginBean.loginAction}"/>
<%}%>
6、在java代码中获取受管bean的属性值
ValueExpression ve=fc.getApplication().getExpressionFactory().createValueExpression(fc.getELContext(), "#{regBean}",regBean.class);
regBean rb=(regBean)ve.getValue(fc.getELContext());
String str=rb.getPwd();
regBean 为受管bean,该段代码采用创建值表达式计算来获取受管bean对象。
另一方法:
FacesContext fc=FacesContext.getCurrentInstance();
Connection conn= (Connection) fc.getApplication().evaluateExpressionGet(fc, this.getConnMBValueEx(), Connection.class);
7、引入自定义标记库时,uri的值有两种写法:1)./WEB-INF/tld/xgtags.tld 2).http://dev.xgtimes.com/java/jsf 第二种写法必须保证xgtags.tld文件中<taglib>标记下的<uri>标记赋值为http://dev.xgtimes.com/java/jsf
8、java.lang.IllegalArgumentException: can't parse argument number loginBean
javax.faces.FacesException: 无法设置管理的 Bean 属性: "logB"。
出现此类错误的原因可能是:你的受管bean的属性使用值表达式来引用其他受管bean时,出现生命周期错误造成的,被引用的受管bean生命周期必须长于或等于本受管bean
9、导航规则中如果使用了from-action,那么该值在形式和内容两者上必须完全等于h:commandButton标签中的action值,否则无效。如:
<from-action>#{regLoginCfg.logB.processLogin}</from-action> 与
<h:commandButton type="submit" action="#{regLogin.processLogin}" value="submit"/>
即使他们指向的都是同一个processLogin方法,该规则同样失效。
10、受管bean初始化顺序
当受管bean第一次被使用时就会被自动创建,创建时JSF先调用bean的构造函数,然后,依次声明各属性,并初始化,如果在xml中配置了属性,则再依次调用相应属性的set方法。
11、使用h:commandLink导航时传递参数的方法:
12、把一个bean注入到另一个bean中,可以使用@Current.(inject one web bean into a field of another using @Current. Web beans will use the type of the field to locate the web bean to be injected.)
举例:(只对JSF2.0有效)
13、代码中的重定向页面的方式:(其中第二种只能针对jsp扩展名的jsf文件)
fc.getExternalContext().redirect("/login.xhtml");
UIViewRoot uiv = new UIViewRoot(); uiv.setViewId("/login.jsp"); fc.setViewRoot(uiv);
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.setHeader("Location", url);