背景
我将使用 java 开发一个新的 Web 应用程序。它不是很大也不是很复杂,我有足够的时间直到它“正式”开始。
我有一些JSF/Facelets开发背景(大约半年)。我对JSP+JSTL也有一些经验。
出于自学目的(也是为了找到最佳解决方案),我想使用基于操作的框架之一来制作新项目的原型。实际上,我会在 Spring MVC 和 Stripes 之间进行选择。
问题
为了获得对基于操作的框架的正确印象(与 JSF 相比),我想确保我正确使用它们(或多或少)。
因此,我在这里列出了一些最常见的任务(至少对我而言),并描述了我如何使用 JSF 解决这些任务。我想知道如何使用基于操作的框架来解决它们(或者如果具体任务有任何差异,则单独使用 Spring MVC 和 Stripes)。
- 渲染内容:我可以从标准 jsf 库(核心和 html)或第 3 方库(如 RichFaces)应用现成的组件。我可以组合简单的组件,并且可以轻松创建基于标准组件的自己的组件。
- 以正确的格式呈现数据(原始或引用类型):每个组件都允许指定一个转换器 用于以两种方式转换数据(渲染和发送到服务器)。像往常一样,Converter 是一个带有 2 个小方法的简单类。
- 站点导航:我指定一组 navigation-cases 在 faces-config.xml 中。然后,我指定应与一个或多个导航案例匹配的链接(或按钮)的操作属性。最佳匹配由 JSF 选择。
- 实现流程(例如多表单向导):我使用的是 JSF 1.2,因此我使用 Apache Orchestra 适用于流程(对话)范围。
- 表单处理:我有一个相当标准的具有一定范围的 java-bean(JSF 术语中的支持 bean)。我在这个 bean 属性上“映射”表单字段。如果一切顺利(没有异常并且验证通过),那么所有这些属性都将使用表单字段中的值进行设置。然后我可以调用一个方法(在按钮的 action 属性中指定)来执行一些逻辑并返回字符串,这应该是我的导航案例之一,可以转到下一个屏幕。
- 表单验证:我可以创建自定义验证器(或从现有验证器中进行选择)并将其添加到几乎每个组件中。 3rd 方库有一组自定义 ajax 验证器。标准验证器仅在页面提交后才起作用。事实上,我不喜欢 JSF 中验证的工作方式。那里的魔法太多了。许多标准组件(或者可能全部)都有预定义的验证,并且不可能禁用它(也许并不总是如此,但我遇到了很多问题)。
- Ajax 支持:许多第 3 方库(MyFaces、IceFaces、OpenFaces、AnotherPrefixFaces...)都具有强大的 ajax 支持,并且运行良好。直到遇到问题。那里也有太多的魔法。如果它不起作用,但你已经按照手册中的描述做了正确的事情,那么让它起作用是非常困难的。
- 用户友好的网址:使用过滤器来完成。但我从来没有尝试过。乍一看似乎太复杂了。
预先感谢您解释如何使用基于操作的框架来完成这些项目(或其中一些项目)。
Background
I'm going to develop a new web-application with java. It's not very big or very complex and I have enough time until it'll "officially" start.
I have some JSF/Facelets development background (about half a year). And I also have some expirience with JSP+JSTL.
In self-educational purpose (and also in order to find the best solution) I want to prototype the new project with one of action-based frameworks. Actually, I will choose between Spring MVC and Stripes.
Problem
In order to get correct impression about action-based frameworks (in comparison with JSF) I want to be sure that I use them correctly (in a bigger or a lesser extent).
So, here I list some most-frequent tasks (at least for me) and describe how I solve them with JSF. I want to know how they should be solved with action-based framework (or separately with Spring MVC and Stripes if there is any difference for concrete task).
- Rendering content: I can apply ready-to-use component from standard jsf libraries (core and html) or from 3rd-party libs (like RichFaces). I can combine simple components and I can easily create my own components which are based on standard components.
- Rendering data (primitive or reference types) in the correct format: Each component allow to specify a converter for transforming data in both ways (to render and to send to the server). Converter is, as usual, a simple class with 2 small methods.
- Site navigation: I specify a set of navigation-cases in faces-config.xml. Then I specify action-attribute of a link (or a button) which should match one or more of navigation cases. The best match is choosen by JSF.
- Implementing flow (multiform wizards for example): I'm using JSF 1.2 so I use Apache Orchestra for the flow (conversation) scope.
- Form processing: I have a pretty standard java-bean (backing bean in JSF terms) with some scope. I 'map' form fields on this bean properties. If everything goes well (no exceptions and validation is passed) then all these properties are set with values from the form fields. Then I can call one method (specified in button's action attribute) to execute some logic and return string which should much one of my navigation cases to go to the next screen.
- Forms validation: I can create custom validator (or choose from existing) and add it to almost each component. 3rd-party libraries have sets of custom ajax-validators. Standard validators work only after page is submitted. Actually, I don't like how validation in JSF works. Too much magic there. Many standard components (or maybe all of them) have predefined validation and it's impossible to disable it (Maybe not always, but I met many problems with it).
- Ajax support: many 3rd-party libraries (MyFaces, IceFaces, OpenFaces, AnotherPrefixFaces...) have strong ajax support and it works pretty well. Until you meet a problem. Too much magic there as well. It's very difficult to make it work if it doesn't work but you've done right as it's described in the manual.
- User-friendly URLs: people say that there are some libraries for that exist. And it can be done with filters as well. But I've never tried. It seems too complex for the first look.
Thanks in advance for explaning how these items (or some of them) can be done with action-based framework.
发布评论
评论(2)
我会尽力回答有关条纹的问题。我过去使用过 Struts 和 JSF,但最近没有使用过,所以我对它们充其量只是有一些模糊的概念和感受。
我们对 Stripes 非常熟悉,现在几乎所有事情都用它,并且非常喜欢它。它很容易上手,支持许多复杂的场景,但您也可以自由地在它之外工作,当您想要构建自己的 ajax 小部件或与另一个系统或其他系统对话时,这一点非常重要。
如果您选择条纹路线,我绝对建议购买或下载这本书。它是您对 Stripes 所需的一切的一站式商店,并且实际上是 Stripersist 的唯一文档(非常好的功能,但没有网络文档)。
渲染内容:我可以从标准 jsf 库(核心和 html)或第 3 方库(如 RichFaces)应用现成的组件。我可以组合简单的组件,并且可以轻松地创建基于标准组件的自己的组件。
这是类似的。 Core、Html、Fmt 等以及您找到的任何自定义标签,包括显示:标签、打包标签并创建您自己的标签。但是,显然您现在不处理组件级别,而是处理一个标记,该标记确定页面上的内容/发送到服务器或从服务器发送的内容。
以正确的格式渲染数据(原始或引用类型):每个组件都允许指定一个转换器,用于以两种方式转换数据(渲染和发送到服务器)。像往常一样,Converter 是一个带有 2 个小方法的简单类。
Stripes 有许多内置转换器,并且可以轻松地为更复杂的数据类型创建自定义转换器。 Stripes 支持非常复杂的数据结构,可以轻松映射。例如,结合 Stripersist,我可以将我的模型对象直接放在 ActionBean 上,在表单上放置一些字段,Stripersist 将从数据库中水化模型(基于其 PK),并使用我在表单上放置的字段更新该模型 - 所有这些都是在将 ActionBean 上的控制权释放给我之前完成的。
站点导航:我在 faces-config.xml 中指定了一组导航案例。然后,我指定应与一个或多个导航案例匹配的链接(或按钮)的操作属性。最佳匹配由 JSF 选择。
条纹中的导航基于您最初为 ActionBean 命名的内容。没有 xml。此外,漂亮的网址是一个Stripes 1.5 中 ActionBean 级别的注释,因此您可以执行
@UrlBinding("/{$event}/{model}")
之类的操作,其中/view/5
会带您进入 ID/PK 为 5 的 Model 对象的“view
”事件处理程序。实现流程(例如多表单向导):我使用的是 JSF 1.2,因此我使用 Apache流程(对话)范围的管弦乐队。
虽然我对对话范围的概念只是模糊地熟悉,但Stripes有向导表单功能,但我没有使用过它,也无法真正扩展它。我认为这是一个类似的想法。
表单处理:我有一个相当标准的java-bean(JSF术语中的支持bean),具有一定的范围。我在这个 bean 属性上“映射”表单字段。如果一切顺利(没有异常并且验证通过),那么所有这些属性都将使用表单字段中的值进行设置。然后我可以调用一个方法(在按钮的操作属性中指定)来执行一些逻辑并返回字符串,这应该是我的导航案例之一,可以转到下一个屏幕。
没有太大不同。您现在拥有 Java 或自定义类型,而不是 [action] bean 上的组件。 ActionBeans 是根据请求创建的并被丢弃,除非您执行诸如将其放入会话、向导或其他任何操作中的操作。这很好,因为所有实例变量都映射到表单中的数据,您使用它,然后扔掉它,并且不必像 struts 那样处理任何同步问题。在您处理完数据后,Stripes 允许您发送 ForwardResolution(正常状态)、重定向或流式传输(JSON、文件等)。 Redirect-after-POST 模式通过 flash 范围 的想法很好地实现了(页面下方 3/4)。
表单验证:我可以创建自定义验证器(或从现有验证器中进行选择)并将其添加到几乎每个组件中。 3rd 方库有一组自定义 ajax 验证器。标准验证器仅在页面提交后才起作用。事实上,我不喜欢 JSF 中验证的工作方式。那里的魔法太多了。许多标准组件(或者可能全部)都有预定义的验证,并且不可能禁用它(也许并不总是如此,但我遇到了很多问题)。
Stripes 允许在 ActionBean 上的实例变量的注释中进行验证。它们允许一些默认值、必需的、最大长度等,或者您始终可以创建自己的。默认设置易于添加且灵活,同时始终能够进行完全自定义的操作。
Ajax 支持:许多第 3 方库(MyFaces、IceFaces、OpenFaces、AnotherPrefixFaces...)都具有强大的 Ajax 支持,并且运行良好。直到遇到问题。那里也有太多的魔法。如果它不起作用,那么很难让它起作用,但你已经按照手册中的描述做了正确的事情。
这是我对 JSF 做事方式的一个大问题。即使您确实正确使用了该小部件,您仍然只能使用该小部件。借助 Stripes,您可以使用任何最新、最好的 Jquery 提供的功能,只要您向服务器发送正确的 GET 或 POST,stripes 就知道如何处理它并可以轻松地发回 JSON。我认为几年前 AJAX 还很困难时,组件框架更适合一个小众市场,但现在 JQ 让它变得如此简单。
用户友好的 URL:人们说有一些库可以实现这一点。也可以通过过滤器来完成。但我从来没有尝试过。乍一看似乎太复杂了。
@UrlBinding,就这么简单。
I'll do my best to answer regarding Stripes. I've used Struts and JSF in the past, but not recently, so at best I have vague notions and feelings about them.
We are intimately familiar w/ Stripes, use it for most everything now, and really enjoy it. It is easy to jump into, supports many of the complicated scenarios, but you are also free to work OUTSIDE of it, which is really important when you want to build your own ajax widgets or talk to another system or something.
If you go the stripes route, I definitely recommend buying or download the book. It is a one stop shop for everything you need for Stripes, and is practically the only documentation for Stripersist (really nice feature, but NO web docs).
Rendering content: I can apply ready-to-use component from standard jsf libraries (core and html) or from 3rd-party libs (like RichFaces). I can combine simple components and I can easily create my own components which are based on standard components.
This is similar. Core, Html, Fmt, etc. as well as any custom tags you find, inc. display:tag, pack tag, and create your own. However, obviously you do not deal at the component level now, you deal with a tag that determines what is on the page / sent to or from the server.
Rendering data (primitive or reference types) in the correct format: Each component allow to specify a converter for transforming data in both ways (to render and to send to the server). Converter is, as usual, a simple class with 2 small methods.
Stripes has many built in converters, and it is easy to create custom converters for your more complex data types. Stripes supports very complex data structures to be mapped with little hassle. Combined with Stripersist, for example, I can put my model object directly on the ActionBean, put a few of the fields on the form, and Stripersist will hydrate the model from the db (based on its PK) and update that with the fields I put on the form - all before releasing control to me on the ActionBean.
Site navigation: I specify a set of navigation-cases in faces-config.xml. Then I specify action-attribute of a link (or a button) which should match one or more of navigation cases. The best match is choosen by JSF.
Navigation in stripes is based on what you name the ActionBeans, initially. There is no xml. Additionally, pretty urls are an annotation at the ActionBean level in Stripes 1.5, so you can do things like
@UrlBinding("/{$event}/{model}")
where/view/5
would take you to the "view
" event handler for your Model object with the ID/PK of 5.Implementing flow (multiform wizards for example): I'm using JSF 1.2 so I use Apache Orchestra for the flow (conversation) scope.
While I only am vaguely familiar with the concept of conversation scope, Stripes has Wizard Form functionality, but I haven't used it and am unable to really expand on that. I think it is a similar idea though.
Form processing: I have a pretty standard java-bean (backing bean in JSF terms) with some scope. I 'map' form fields on this bean properties. If everything goes well (no exceptions and validation is passed) then all these properties are set with values from the form fields. Then I can call one method (specified in button's action attribute) to execute some logic and return string which should much one of my navigation cases to go to the next screen.
Not drastically different. Instead of components on your [action] bean, you now have Java or custom types. ActionBeans are created per request and thrown away, unless you do something like put it in session, or wizard, or whatever. This is nice, because all the instance variables get mapped to the data from the form, you use it, then throw it away, and don't have to deal with any synchronization issues like struts did. After you do your thing with the data, Stripes lets you send a ForwardResolution (OK status), Redirect, or Streaming (JSON, file, etc). The Redirect-after-POST pattern is implemented nicely with the idea of flash scope (3/4 down the page).
Forms validation: I can create custom validator (or choose from existing) and add it to almost each component. 3rd-party libraries have sets of custom ajax-validators. Standard validators work only after page is submitted. Actually, I don't like how validation in JSF works. Too much magic there. Many standard components (or maybe all of them) have predefined validation and it's impossible to disable it (Maybe not always, but I met many problems with it).
Stripes allows validation in annotations on the instance variables on the ActionBean. They allow some defaults, required, maxlength, etc. or you can always create your own. The default is easy to add and flexible, while there is always the ability to make something completely customized.
Ajax support: many 3rd-party libraries (MyFaces, IceFaces, OpenFaces, AnotherPrefixFaces...) have strong ajax support and it works pretty well. Until you meet a problem. Too much magic there as well. It's very difficult to make it work if it doesn't work but you've done right as it's described in the manual.
This was my big problem with the JSF way of doing things. Even if you did get the widget right, you're still stuck with THAT widget. With Stripes, you can use whatever latest and greatest Jquery has to offer, and as long as you send the right GET or POST to the server, stripes knows what to do with it and can easily send JSON back. I think component frameworks fit a niche a few years ago much better when AJAX was hard, but JQ makes it so easy now.
User-friendly URLs: people say that there are some libraries for that exist. And it can be done with filters as well. But I've never tried. It seems too complex for the first look.
@UrlBinding, it's as easy as that.
我的答案不是您想听到的:不要从组件框架切换到操作框架
在多年的操作框架开发之后,我换了另一种方式,并且我永远不会回头。
在您提到的 8 个用例中,只有一个 Action 框架明显更好,那就是 URL 设计/友好的 URL。它也可以在组件框架中完成,但在 Action 框架中更容易(特别是在 Stripes 中,您只需使用 url 注释 ActionBean)。
我建议您尝试 wicket,它非常容易学习(比 JSF 容易得多),并且它还可以让您重用许多现有组件。
My answer is not the one you want to hear: Don't switch from Component Framework to action framework
I switched the other way around after many years of action framework development and I'm never going back.
Of the 8 use cases you mentioned, only one comes to mind where Action frameworks are obviously better, and that is URL design / friendly URLs. It can be done in component frameworks as well, but much easier in Action Frameworks (especially in Stripes where you just annotate your ActionBean with the url).
I would advise you to try wicket, it is very easy to learn (much easier than JSF) and it let's you re-use many existing components as well.