[Ajax4JSF] jsf几个常用取值方法和技巧总结(持续更新)
kimmking
2008-05-20
jsf几个常用取值方法和技巧总结(持续更新)
1、获取managedbean或是解析表达式 有三种方法 (1) FacesContext context =FacesContext.getCurrentInstance(); ValueBinding binding = context.getApplication().createValueBinding("#{bean}"); YourBean bean = (YourBean ) binding.getValue(context); (2) FacesContext ctx = FacesContext.getCurrentInstance(); VariableResolver variableResolver =ctx.getApplication().getVariableResolver(); YourBean bean = (YourBean ) variableResolver.resolveVariable(ctx, "bean"); (3) Application application=context.getApplication(); YourBean ManageBeanProperty=(YourBean )application.evaluateValueExpressionGet(context,"#{bean}",YourBean .class); 第3种方法只对jsf1.2可用。(evaluateValueExpressionGet方法1.1种没有) 其实还有一种方法。后面会提到。 2、对于已知范围和名字的bean,可以 externalContext.getRequestMap().get(beanName) externalContext.getSessionMap().get(beanName) externalContext.getApplicationMap().get(beanName) 3、FacesContext 组件实例相关 facesContext.getViewRoot() 可以获取ViewRoot,然后递归循环其children得到整个组件树, 可以实现: (1)根据组建id得到组件。 (2)得到form,添加新的组件到此集合,或是改变form的属性。 (3)得到某个类型的所有组件,然后加上监听器。 。。。。。 从这个root入手,再加上事件,绑定和分析,几乎可以完全控制整个组件树。 4、Application 获取方式Application application=facesContext.getApplication(); 用处可以见下面的代码: (1)组件类型的注册和组件集合的获取 (2)converter,validator的。。。 (3)属性分析器和变量分析器的。。。 (4)NavigationHandler、ViewHandler.... (5)添加一个listener (6)创建一个组件的实例 (7)创建一个值绑定或方法绑定 大部分全局性配置的东西都在这儿可以找到。而且几乎都是可以热替换的。 其中5、6比较常用。 5、RuntimeConfig 获取方式RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(); 两个功能: (1)获取配置文件中所有的导航规则,或者运行时添加新的导航规则。 (2)获取配置文件中所有的managedmean类型,或者运行时添加一个新的managedmean类型。 第一条可以实现通过一个给定的url,动态添加一条规则,然后在action中return起outcome字符串。 后一条可以获取给定的bean的class全称,实例化一个bean。或者动态配置一个bean。 6、ExternalContext servlet相关操作和各种参数 (1)获取response和request、session、servletContext (2)redirect和dispacth (3)获取resquest、session、application、servlet参数 (4)获取资源和url本地路径 (5)encode url create by qinjinwei last modified at 2008年5月5日18:09:45 7、绑定List和Map 使用JSF开发时,经常遇到要把MBean中的一个List或Map中的值通过EL显示在页面上,EL中访问Map或List的方法如下: 假设FacesConfig中配置一个bean的MBean,它的类中定义了一个List类型的list属性和一个Map型的map属性。 首先是访问List,页面中引用bean中list属性的方法为:#{bean.list[index]} 而对于Map,EL可以把Key作为一个属性来读取,因此对map的访问可以写为:#{bean.map.key},当然这样可以解决基本的问题,但是如果map中的key是一个包含了空格或特殊字符的String,那么很明显,这个字符串不符合作为属性名的条件,那么用上面的方法去访问明显是有问题的,所以我们很可以用另外一种方法访问Map中的value,#{bean.map['key']}。同时可以看到,因为EL中的内建对象基本都是用Map实现的,因此,EL中的访问方法也是:#{sessionScope['key']}。 8、JSF动态为DataTable添加列 开发JSF的朋友可能会遇到这样的问题,如果DataTable的列不固定,需要动态生成, 该如何实现呢。 假设FacesConfig中配置一个名为bean的MBean,该MBean中需定义一个类型为javax.faces.component.html.HtmlDataTable类型的变量dt,页面中的DataTable设置bingding="#{bean.dt}"。 首先了解一下JSF中DataTable的渲染方式: DataTable --<Header> UIComponent --<Children>List<HtmlColumn> ----<HtmlColumn> ------<Header>UIComponent ----<Children>List<UIComponent> 因此,要在后台变更DataTable的状态,可以用dt.setHeader(UIComponent)设置DataTable的表头,然后可以往dt.getChildren()中添加HtmlColumn类型的列,同样,列中也可以由Header和Children组成。代码实现如下: private void initialReportTable(List<ExcelReport> reportList) ...{ dt.getChildren().clear(); for (ExcelReport report : reportList) ...{ HtmlColumn column = new HtmlColumn(); HtmlOutputText header = new HtmlOutputText(); header.setValueExpression("value", getValueExpression("#{rmaReport.captions.c" + report.getPosition() + "}")); column.setHeader(header); HtmlOutputText value = new HtmlOutputText(); String ve = getVEString(report); System.out.println(report.getCaption() + " : " + ve); value.setValueExpression("value", getValueExpression(ve)); column.getChildren().add(value); dt.getChildren().add(column); } }其中,动态建立控件的方法为直接创建一个控件,然后通过ValueExpression来设置控件在运行时显示的值,如果是Column中的数据,则可以使用#{tableVar.ColumnName}格式的EL表达式。 9、 JSF动态生成组件 用过Servlet和JSP的开发者对动态生成组件应该是情有独钟了,可以根据数据的情况生成特定的组件,这样增大了Form的灵活性,那么JSF中如何生成动态的窗体呢,其实非常简单。主要逻辑就是通过FacesContext得到viewRoot对象,然后通过viewRoot对象的getChildren方法可以得到viewRoot下的所有第一级组件,然后分别对每个组件的getChildren方法进行递归调用,就可以得到整个组件树,当然可以对某个组件的getChildren得到的List使用add方法添加组件了,代码如下,页面有两个commandButton,其中一个可以添加一个TextBox控件,另外一个可以在console打印出当前的组件列表。 package net.moon; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.component.UIViewRoot; import javax.faces.component.html.HtmlInputText; import javax.faces.context.FacesContext; public class DymaComponent ...{ private UIViewRoot viewRoot; private static int inputIndex = 0; private List<UIComponent> getComponentChildren(UIComponent component)...{ List<UIComponent> componentList = null; System.out.println(component.getId()); if(component.getChildCount() > 0)...{ for(UIComponent ui : component.getChildren())...{ componentList = getComponentChildren(ui); } } return componentList; } public String getComponentsList()...{ viewRoot = FacesContext.getCurrentInstance().getViewRoot(); for(UIComponent component : viewRoot.getChildren())...{ getComponentChildren(component); } return null; } public String addTextBox()...{ viewRoot = FacesContext.getCurrentInstance().getViewRoot(); UIComponent form1 = viewRoot.getChildren().get(0); HtmlInputText input = new HtmlInputText(); input.setId("input" + (inputIndex++)); input.setValue("Input 1"); input.setRendered(true); form1.getChildren().add(input); return null; } } <%...@ page contentType="text/html; charset=UTF-8" %> <%...@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%...@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title></title> </head> <body> <f:view> <h:form id="form1"> <h:commandButton id="commmand1" action="#{dymaComponent.getComponentsList}" value="Print ViewRoot"></h:commandButton> <h:commandButton action="#{dymaComponent.addTextBox}" value="Add TextBox"></h:commandButton> </h:form> </f:view> </body> </html> <?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" version="1.2"> <managed-bean> <managed-bean-name> dymaComponent</managed-bean-name> <managed-bean-class> net.moon.DymaComponent</managed-bean-class> <managed-bean-scope> session</managed-bean-scope> </managed-bean> </faces-config> PS:7-9条来自http://blog.csdn.net/sunshinestation |
|
terryzhou
2008-05-21
不错..
支持 |
|
yunhaifeiwu
2008-05-21
在jsf 的bean与bean之间的交互,我以为通过这样的方式较好,不知各位意下如何?
假这othenBean之other要访问UserBean之user中的数据。 可以先在othenBean中增加一个属性,userProperty,其类型为UserBean 然后在bean配置中相应更改 <managed-bean> ______<managed-bean-name>user</managed-bean-name> _________<managed-bean-class> ____________webapplication1.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> _____webapplication1.OtherBean __</managed-bean-class> __<managed-bean-scope>session</managed-bean-scope> __<managed-property> _____<property-name>userProperty </property-name> _____<value>#{user}</value> __</managed-property> </managed-bean> 其中,#{user} 表示对已经规定了的bean的引用。 本例中:设定了两个bean,UserBean 、OtherBean ,它们的实例名为user与other. 其中other中的有一个属性(userProperty)其值设成user. |
|
kimmking
2008-05-21
session的话 这个是建议的方式 (IOC)
其他方式 valuebinding、 sessionMap都不如这个方便 |
|
terryzhou
2008-05-21
session bean不建议太多..
非session bean 互相visit又没啥意义.. 调spring的bean倒是用的到.. |
|
kimmking
2008-05-21
bean的相互调用 我一般不这么做
觉得结构不清晰 |
|
vieri122
2008-06-24
看完了 写的真好
期待楼主再接再厉~! |
|
bengan
2008-11-24
好材料~~怎么没有收藏啊?
|
|
huahuashijie888
2008-12-05
在jsf页面的文件打开组件
<h:outputText value="原文:"/> <h:commandLink title="#{Taskprogress.originaltext}" styleClass="uploadFile" action="#{Taskprogress.openOriginalFile}"> <h:outputText id="originaltext" value="#{Taskprogress.originaltext}"> </h:outputText> </h:commandLink> 当我点击链接的时候,跳出文件对话框,执行保存,打开,或者取消操作后,我再保存当面页面,但是又会跳出文件下载对话框,action源码如下: public static void openFile(String fileName,String subDir) { try { HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); if(FacesContext.getCurrentInstance().getResponseComplete())return; if (!subDir.equals("")) subDir = subDir + "\\"; fileName = request.getRealPath("upload")+"\\" + subDir + fileName; java.io.File f = new java.io.File(fileName); if (f.exists()&&f.canRead()) { response.setContentType ("application/x-msdownload octet-stream;charset=ISO8859-1"); response.setHeader ("Content-Disposition", "attachment;filename=\"" + new String(f.getName().getBytes(), "ISO8859-1") + "\""); // response.setContentLength((int) f.length()); java.io.BufferedInputStream fileInputStream = new java.io.BufferedInputStream(new java.io.FileInputStream(f)); int i; // java.io.OutputStream out = response.getOutputStream(); java.io.PrintWriter out = response.getWriter(); // out.clearBuffer(); while ((i=fileInputStream.read()) != -1) out.write(i); fileInputStream.close(); out.flush(); out.close(); FacesContext.getCurrentInstance().responseComplete(); } } catch (IOException e) { e.printStackTrace(); } // String fileType = fileName.substring(fileName.lastIndexOf(".")+1); // if (fileType.equals("doc")) // openWordFile(fileName); // else if (fileType.equals("xls")) // openExcelFile(fileName); } 为什么不能结束本次请求?想半天了,麻烦指点指点! |
|
will-vip
2009-02-01
收藏下,还没有用到jsf动态生成页面
|