Spring和JSF集成:导航

我希望这是有关我在Spring和JavaServer Faces之间提供深度集成的努力的一系列博客中的第一篇。 这里提到的所有内容都是“正在进行中的工作”,因此,如果您签出代码,请注意它是一个不断变化的目标。 期待一些粗糙的边缘,如果有时会断裂,不要感到惊讶。

您已经可以很轻松地使用带有JSF的Spring,Spring可以管理bean和JSF来处理屏幕。 Spring Web Flow中还对JSF提供了一些非常好的支持,如果您正在做任何基于流的应用程序,那么您确实应该使用Web Flow。 Web Flow还提供org.springframework.faces.mvc. JsfView类,使您可以从Spring MVC呈现JSF页面。 不幸的是, JsfView仅呈现瞬态(无状态)视图,如果您想处理回发,则JsfView走运。

允许Spring MVC渲染可以处理回发的JSF视图一直是我启动该项目的主要动力。 得益于MVC和JSF的灵活性,完全可以集成这些技术(尽管关于如何最好地保存其他帖子的确切细节)。 我想在本文的其余部分中讨论如何创建非常好的JSF导航。

如果您使用了标准的JSF导航,那么您可能已经习惯了faces-config.xml的以下类型的事情:

<navigation-rule><from-view-id>/pages/list.xhtml</from-view-id><navigation-case><from-outcome>select</from-outcome><to-view-id>/pages/details.xhtml</to-view-id><redirect/></navigation-case>
</navigation-rule>

虽然很容易理解,但是对于标准方法来说,标准方法存在一些明显的缺点,因为它非常冗长。 大多数时候,我想重定向我的用户,而不是让他们困惑为什么URL显示与当前页面不同的内容。 实际上在每个元素上都需要<redirect/>确实很烦人。 XML的数量显然使JSF的开发人员感到不安,幸运的是,JSF 2.0引入了隐式导航的概念。 这是我们稍后将使用的东西。 如果您想阅读有关JSF导航的非常好的文章,请使用Dan Allen撰写的JSF 2中的Fluent Navigation 。

导航实际上是关于目的地的,将某人重定向到404 page not found错误没有多大意义。 对于JSF而言,创建漂亮的可读URL目标始终是一件艰辛的事情。 现在,在不开发自己的代码的情况下,创建可读URL的最佳选择可能是使用PrettyFaces 。 当然,通过将JSF和Spring很好地集成在一起,您不需要使用@RequestMapping注释以外的任何其他东西来创建可读的URL。 下面的示例演示如何映射一个可读的URL,以显示ID中的酒店详细信息。

@Controller
public class HotelsController {@RequestMapping(value = "/hotels/{id}", method = RequestMethod.GET)public String show(@PathVariable Long id, Model model) {model.addAttribute(bookingService.findHotelById(id));return "hotels/show";}
}

有了@RequestMapping批注,我们可以再次考虑导航。 通常, <h:commandButton><h:button><h:commandLink><h:link>组件将用于触发导航,例如:

<h:commandButton value="Go" action="select">

在此,当用户单击"Go"按钮时, "select"动作开始,并且导航规则用于查找目的地。 当我们要远离定义导航XML时,我们需要另一种方法来查找MVC目标。 稍微颠覆JSF对隐式导航的支持为我们提供了一种很好的方法。 通过一些集成代码,我们可以支持特殊的"spring:"前缀,该前缀告诉JSF使用Spring MVC解析目标。

<h:commandButton value="Go" action="spring:redirect:/spring/hotels/123"/>

上面的示例将使用在Spring MVC中注册的ViewResolver解析"redirect:/spring/hotel/123" 。 在这种情况下, UrlBasedViewResolver将选择"redirect:"并将使用RedirectView
很好,但是将酒店ID "123"硬编码到视图名称中并不是很实际。 幸运的是有一个答案:

<h:commandButton value="Go" action="spring:redirect:/spring/hotels/{id}"><f:param name="id" value="#{resultItem.id}/>
</h:commandButton>

commandButton所有<f:param>子标记将用于构造MVC视图的模型。 在这种情况下,我们得到一个包含“ id=#{resultItem.id} ”的模型。 EL值表达式#{resultItem.id}将在呈现视图之前解析。 Spring 3.1中的RedirectView类将处理URL模板变量,因此“ /spring/hotels/{id} ”将选择“ id ”以呈现完整的URL。

使用上述方法的一点烦恼是您需要在XHTML文件以及@RequestMapping批注中定义URL。 作为替代方案,您可以使用特殊的“ @bean.method ”符号表示您要导航至指定控制器bean方法上的@RequestMapping的值:

<h:commandButton value="Go" action="spring:@hotelsController.show"><f:param name="id" value="#{resultItem.id}/>
</h:commandButton>

如果在控制器bean上有多个@RequestMapping方法,则可以使用更短的语法“ @method ”(此处假定该bean是当前处理程序)在它们之间进行导航。 当然,并非每种类型的@RequestMapping都可以反向转换为URL,例如,如果您使用通配符,则此操作将无效。 建议是使您的映射尽可能简单。
这种方法的最后一个好处是我们还可以逆转DataBinder过程。 例如:

public class SearchCriteria implements Serializable {private String searchString;private int page;// ... getters / setters
}
@RequestMapping(value = "/hotels")
public String list(SearchCriteria criteria, Model model) {// ...
}
<h:link outcome="spring:@list"><f:param name="sc" value="#{searchCriteria}"/>
</h:link>

假定#{searchCriteria} EL表达式解析为包含字符串"California"SearchCriteria对象,并且所构建的URL的整数10将为"/spring/hotels?searchString=California&page=10"

如果您想查看该项目的代码,可以在http://github.com/philwebb/springfaces上找到它。 如文章顶部所述,此代码尚在开发中,因此请注意一些问题。 路线图上的下一个任务是支持@NavigationMapping批注,该批注将允许以编程方式进行导航。

参考: 集成Spring和JavaServer Faces: JCG合作伙伴 Phillip Webb的 导航   在Phil Webb的Blog上 。


翻译自: https://www.javacodegeeks.com/2012/03/spring-jsf-integration-navigation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CSS3动画】transform对文字及图片的旋转、缩放、倾斜和移动

前言&#xff1a;之前我有写过CSS3的transform这一这特性&#xff0c;对于它的用法&#xff0c;还不是很透彻&#xff0c;今天补充补充&#xff0c;呵呵 你懂的&#xff0c;小司机准备开车了。 a)再提一提transform的四个属性 ①旋转--->rotate(参数a)&#xff0c;单位deg&a…

宏的用法与简介

预处理指令&#xff1a;例如&#xff1a;#include<stdio.h> #include<stdlib.h> #define MAX 20 ............. 因为他们由预处理器解释的&#xff0c;所以称作预处理指令。预处理器读取源代码&#xff0c;然后对其修改&#xff0c;并把修改过的…

django 日志写入mysql_如何将django orm模型 写入数据库

1、指定连接pymysql(python3.x)先配置_init_.pyimport pymysqlpymysql.install_as_MySQLdb()2、配置连接mysql文件信息settings.pyDATABASES {default: {ENGINE: django.db.backends.mysql,NAME: django_orm, #你的数据库名称USER: root, #你的数据库用户名PASSWORD: , #你的数…

ORM的问题第2部分–查询

在我以前关于对象关系映射工具&#xff08;ORM&#xff09;的帖子中&#xff0c;我讨论了在处理当今常见的ORM&#xff08;包括Hibernate&#xff09;时遇到的各种问题。 其中包括与从POJO生成架构有关的问题&#xff0c;实际性能和不断出现的维护问题。 本质上&#xff0c;结论…

【转】如何减少接口响应时间

Premature optimization is the root of all evil. — Donald Knuth 对于程序优化&#xff0c;我一直采取保守的态度&#xff0c;除非万不得已。但是随着业务的不断发展&#xff0c;程序越来越复杂&#xff0c;代码越写越多&#xff0c;优化似乎是终有一天会到来的事情。 那么对…

数据库行转列在现实需求中的用法

select t.客户姓名,sum(case when t.收款类型首款 then t.金额 else 0 end as 首款),sum(case when t.收款类型尾款 then t.金额 else 0 end as 尾款) from table t group by t.客户姓名 这段sql的意思 是 查询出所有客户收款信息 然后按客户分组 分组后 然后将这个客户的所…

mysql生产环境加索引_【生产篇】_MySQL环境下如何查看基于表的索引定义

【引言】今天中午项目组来一需求&#xff0c;欲在MySQL环境的某张表下创建几个BTREE索引。要创建索引&#xff0c;首先需要了解基表的表结构&#xff0c;以及已经包含的索引。Oracle的表结构大家都很熟悉&#xff0c;但MySQL表结构和已创建索引的查看怎么操作&#xff0c;本文将…

Hadoop模式介绍-独立,伪分布式,分布式

了解了什么是Hadoop之后&#xff0c;让我们在单机上启动Hadoop&#xff1a; 这篇文章包含在ubuntu上安装Hadoop的说明。 这是Hadoop安装的快速分步教程。 在这里&#xff0c;您将获得以独立模式 &#xff08;单节点集群&#xff09;安装Hadoop所需的所有命令及其说明&#xff0…

apk反编译方式

一、Apk反编译得到Java源代码 下载上述反编译工具包&#xff0c;打开apk2java目录下的dex2jar-0.0.9.9文件夹&#xff0c;内含apk反编译成java源码工具&#xff0c;以及源码查看工具。 apk反编译工具dex2jar&#xff0c;是将apk中的classes.dex转化成jar文件 源码查看工具jdgui…

优化Hibernate所鼓励的7大措施

优化Hibernate所鼓励的7大措施&#xff1a; 1.尽量使用many-to-one&#xff0c;避免使用单项one-to-many2.灵活使用单向one-to-many3.不用一对一&#xff0c;使用多对一代替一对一4.配置对象缓存&#xff0c;不使用集合缓存5.一对多使用Bag 多对一使用Set6.继承使用显示多态 HQ…

如何用c 控制mysql数据库_用C语言操作MySQL数据库

函数描述mysql_affected_rows()返回上次UPDATE、DELETE或INSERT查询更改&#xff0f;删除&#xff0f;插入的行数。mysql_autocommit()切换autocommit模式&#xff0c;ON/OFFmysql_change_user()更改打开连接上的用户和数据库。mysql_charset_name()返回用于连接的默认字符集的…

数据结构(RMQ):POJ 3624 Balanced Lineup

Balanced LineupDescription For the daily milking, Farmer Johns N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a conti…

Apache Thrift快速入门教程

Thrift是一种跨语言RPC框架&#xff0c;最初是在Facebook上开发的&#xff0c;现在作为Apache项目开源。 这篇文章将描述如何以不同的模式&#xff08;例如阻塞&#xff0c;非阻塞和异步&#xff09;编写Thrift服务和客户端。 &#xff08;我觉得后两种模式的文档较少&#xff…

数组拆分为新数组

package com.classes;//已知数组a&#xff0c;将奇数位置元素存到b数组中&#xff0c;偶数位置元素存到c数组中public class Shuzu1118_4 { public static void main(String[] args) { int [] a{3,6,9,1,4,7,2,5,8}; int [] b; //定义数组b int [] c; //定义数组c//先找出数组…

java数组交集_java数组的交集和并集

前两天给我出了一道题&#xff0c;求数组的并集和交集&#xff0c;然后我试着写一下&#xff0c;很尴尬&#xff0c;由于长时间没有写过代码&#xff0c;一开始数组是如何定义的给忘了。当时我说了我的思路&#xff0c;不过也是很low的做法&#xff0c;查阅网上的一些资料&…

ADF声明性组件示例

在我以前的文章中&#xff0c;我答应展示如何为智能值列表创建ADF声明性组件。 因此&#xff0c;我将创建一个包含三个元素的组件&#xff1a;标签&#xff0c;输入文本和值的组合框列表。 那很容易。 我在工作空间中创建了一个单独的ADF ViewController项目&#xff1a; 在此项…

VS2015 安装包缺失(联网安装失败)问题解决

Win7 x86 测试可行 * 如果前面有尝试过安装不成功, 一定要用卸载程序删除已安装的部分,否则会出乱子. 1. 或者是用虚拟光驱加载ISO, 或者是解压到硬盘上, 都没有关系. 2. 用管理员权限启动CMD控制台, 进入VS2015 安装盘的根目录 (vs_enterprise.exe 所在的目录). 3. 执行命令 …

java蓝桥暑假班_Java实现 蓝桥杯VIP 算法提高 班级排名

算法提高 班级排名时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB问题描述达达在陶陶的影响下&#xff0c;也对学习慢慢的产生了兴趣。他在每次考试之后&#xff0c;都会追着老师问&#xff0c;自己在班级的总名次是多少。考试一多&#xff0c;老师也不耐烦了&#xff…

$.ajax所犯的错误。success后面不执行

$.ajax({ type: post, url: ../AshxHandler/HandlerAddPhoto.ashx, data: { clientPath: photoName }, dataType: text, cache: false, success: function (data) { alert(1); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(上传图片出现错误&#xf…

WhateverOrigin –与Heroku和Play对抗相同的原产地政策! 构架

不久前&#xff0c;我在编码 Bitcoin Pie时发现需要克服臭名昭著的Same Origin Policy &#xff0c;该政策限制了运行在客户端浏览器上的javascript可以访问的域。 通过Stack Overflow&#xff0c;我找到了一个名为Any Origin的站点&#xff0c;这基本上是无需设置专用服务器即…