JSF 导航规则(Navigation)学习笔记
JSF 导航规则
静态导航
静态导航规则实例
JSF框架导航处理器(Navigation Handler)在未直接找到结果对应导航规则时,会触发静态导航。采用静态导航规则处理action返回的结果(out-come),获取导航目标页面的标示符,导航到对应的页面。
<h:commandButton label="Login" action="welcome"/>
或者
<h:commandLink label="Login" action="welcome"/>
静态导航执行流程
JSF导航控制器(Navigation Handler),首先在配置中查找out-come为welcome的导航规则,未找到对应的导航规则。采用静态导航规则处理out-come的值,获取导航到的目标页面的标示符,导航到目标视图页面。
静态导航处理规则
-
若out-come不带页面的后缀名,则将out-come值上加当前视图页面的后缀名;否则不做处理。
-
如果out-come的值不以"/"开头,则在out-come前加上当前请求页面所在的相对路径。
经过上述处理规则,导航处理器获取目标页面的标示符,导航到对应的页面。
动态导航
动态导航实例:
<h:commandButton label="Login" action="#{user.doLogin}"/>
<h:commandLink label="Login" action="#{user.doLogin}"/>
faces-config.xml中导航规则配置:
JSF处理完action完成业务逻辑操作,会根据action返回的out-come,查找配置的导航规则,若找到该导航规则,则导航至规则配置的目标页面。
动态目标页面导航
to-view-id 标签内可以是常量值,也可是求值表达式,但必须以"/"开头;而from-view-id标签内只能为常量值。to-view-id标签为求值表达式时,称为动态目标页面导航,这是JSF2.0新增的高级特性之一。示例如下:
全局导航规则
若省略from-view-id元素,表示此导航该规则是全局导航规则,对所有返回out-come符合from-outcome业务操作,应用此导航规则。示例如下
from-action区分导航
若两个action返回的from-outcome相同,如何区分其导航规则呢?一种方式是通过from-view-id元素,另一种方式则是通过from-action元素。示例如下:
from-action区分导航注意点:
from-action仅仅用来区分from-out来源的action,在导航时并不调用from-action对应的方法。
条件导航
JSF2.0提供了一种if的元素,只要当if条件满足时,才会使用该导航规则。条件导航示例如下:
其它导航处理规则
-
to-view-id若无后缀名,则加上前请求视图的的后缀名。
-
#{user.doLogin} 返回类型可以是String类型,也可以是任何object类型。若返回类型为object,导航处理器会调用对象上的toString(),获取string类型处理结果(outcome)
-
若#{user.doLogin}返回为null或者空字符串等,且未找到匹配的导航规则,则再次渲染当前页面。
-
导航规则from-outcome元素若不配置,则当前页面未找到返回out-come对的导航规则,则导航到该规则对应的目标页面。
-
from-view-id可采用通配符配置,选取符合通配符页面适用此导航规则(注意:通配符只能带一个星号,而不能连续两个或多个星号。这是JSF2.0 的高级属性)示例如下:
外部重定向(redirect)
JSF默认采用post方式进行数据处理,采用内部定向(forward)的方式,控制页面之间在服务器上的流动,而浏览器端的地址栏网址保持不变。有时需要用户收藏某个页面的网址,就需要将浏览器的网址变为实际的地址。这是就需要采用外部重定向(redirect)的导航,让浏览器网址变为当前页面的地址,以便用户收藏。
JSF导航重定向的两种方式
-
Xml配置的方式
-
在请求中action增中添加faces-redirect参数
外部重定向请求处理流程
-
浏览器发送请求到服务器
-
服务器执行完成业务操作
-
服务器向浏览器发送302响应以及要重定向到的地址
-
浏览器收到响应,向重定向的地址发送请求
-
服务器收到浏览器的请求,执行业务操作渲染从定向的页面
弊端:外部重定向(redirect)增加请求次数,加重服务器和浏览器之间的通信开销,会对性能有一定损耗。
注意:从定向相当于发送的一次新的请求,因此request周期的bean信息在下次请求会从新初始化。
重定向参数的保存与传递
有时需要将信息保存到下次请求,以便重定向时进行渲染。这时需要把信息放到flash范围(保存至下一个请求)生命周期的map中,即可将信息保存到下次请求,实现方式如下:
或者
展示flash的map中包含的信息方法如下:
#{message} 或 #{flash.message}
从定向(redirect)也可通过URL传递参数(JSF2.0高级特性),实现方式如下:
-
<h:commandLink action="index?faces-redirect=true&includeViewParams=true">
post方式不支持通过内嵌f:param的方式传递或覆盖参数。
-
通过xml配置
提示:注意两种方式include-view-params参数的名字的区别
RESTfull及可收藏的网址导航
RESTfull简述
JSF默认使用内部定向的post请求方式导航页面的直接的流动,这种方式适用于重业务型、多输入的场景;但绝大多数互联网应用场景并非这样,而是输入处理操作较少,读取操作极多的场景。
用户选择一个链接,点击到另一个页面,这个链应该是可被收藏的。用户下次输入这个链接时,能到达相同的页面。且页面缓存对提升互联网应用的性能有很大的帮助,因此页面应该是可以被缓存的。Post请求由于其自身的特点,却无法缓存或者被收藏。由此互联网出现了一种叫做REST(显现状态迁移)的架构;该架构约定:读取、查找操作必须为get请求,创建、修改、删除的操作必须采用put、post、delete请求。
Rest架构推荐的优雅URL的风格如下:
但并不要求URL必须按照上述风格,下面URL也是RESTfull的
Get请求应该是自包含的、无状态的、对等的。一个相同URL的不同get请求,响应的内容应该相同,而与其它页面的状态无关,这样get请求页面就可被缓存起来。
JSF规范本身未定义产生及解析RESTfull风格的优雅URL的机制;但JSF 2.0起,开始支持GET请求。
生成GET请求的方法
常用生成GET请求链接采用h:button 或 h:link 标签生成
h:button、h:link在页面渲染前就会进行outcome求值,这种方式称为预导航。与之对应的h:commandButton、h:commandLink生成post请求,在用户点击按钮或链接时才会触发outcome对应的action。
Get请求携带参数的方式
GET请求URL通常包含特定的参数,参数生成可由以下三种方式生成:
-
outcome中自带参数
<h:link outcome="index.xhtml?q=1" value="查询">
<h:link outcome="index.xhtml?q=1&score=99">
注意: 带多个参数时要转义&字符。
-
自动包含页面的参数
<h:link outcome="index" includeViewParams="true" value="下一页">
自动将当前该页面的所有参数附加到生成的链接中。如果要附带或覆盖其中的某个参数,则可采用f:param标签:
<h:link outcome="index" includeViewParams="true" value="下一页">
<f:param name="q" value="#{quizBean.currentNum + 1}"/>
</h:link>
-
内嵌f:param标签
<h:link outcome="index" >
<f:param name="q" value="#{quizBean.currentNum + 1}"/>
</h:link>
如何获取URL中的参数
如何获取请求url中参数呢?有以下三种方式:
-
JSF2.0提供的<f:metadata>标签,示例如下:
<f:metadata>
<f:viewParam name="score" value="#{bean.score}">
</f:metadata>
该标签在请求被处理时被填充到bean中,也可在填充前进行转换及验证操作。
-
JSF框架内置变量param获取
#{param.score}
或者
@ManagedProperty(value="#{param.score}")
private Long score;
-
通过编码获取
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
Map map = extContext.getRequestParameterMap();
String score = (String)map.get("score");
转载地址:http://gubaojian.blog.163.com/blog/static/1661799082012368846683/#_Toc321506201