昨天我看了一个关于Java Server Faces 2.0的演示,它看起来确实令人印象深刻,尽管我现在是一个快乐的ASP。asp.net MVC / jQuery开发。我最喜欢JSF的地方是它有大量支持ajax的UI组件,这使得开发比使用ASP要快得多。NET MVC,特别是在ajax较多的站点上。集成测试看起来也很不错。

由于这个演示只强调了JSF的优点,所以我也想听听其他方面的情况。

所以我的问题是:

Java Server Faces 2.0的主要缺点是什么? 什么会使JSF开发人员考虑使用ASP。NET MVC而不是JSF?


JSF 2.0的缺点?老实说,如果你没有基本的Web开发(HTML/CSS/JS,服务器端与客户端,等等)和基本的Java Servlet API(请求/响应/会话,转发/重定向,等等)的扎实背景知识,除了相对陡峭的学习曲线,没有什么严重的缺点会出现在你的脑海中。JSF在当前的发行版中仍然需要摆脱它在早期获得的负面形象,在早期有几个严重的缺点。

JSF 1.0(2004 年 3 月)

这是最初的版本。它在核心和性能领域都充斥着你不想知道的bug。您的web应用程序并不总是像您直观地期望的那样工作。作为开发者的你会哭着跑开。

JSF 1.1(2004 年 5 月)

This was the bugfix release. The performance was still not much improved. There was also one major disadvantage: you can't inline HTML in the JSF page flawlessly. All plain vanilla HTML get rendered before the JSF component tree. You need to wrap all plain vanilla in <f:verbatim> tags so that they get included in the JSF component tree. Although this was as per the specification, this has received a lot of criticism. See also a.o. JSF/Facelets: why is it not a good idea to mix JSF/Facelets with HTML tags?

JSF 1.2 (2006 年 5 月)

This was the first release of the new JSF development team lead by Ryan Lubke. The new team did a lot of great work. There were also changes in the spec. The major change was the improvement of the view handling. This not only fully detached JSF from JSP, so one could use a different view technology than JSP, but it also allowed developers to inline plain vanilla HTML in the JSF page without hassling with <f:verbatim> tags. Another major focus of the new team was improving the performance. During the lifetime of the Sun JSF Reference Implementation 1.2 (which was codenamed Mojarra since build 1.2_08, around 2008), practically every build got shipped with (major) performance improvements next to the usual (minor) bugfixes.

The only serious disadvantage of JSF 1.x (including 1.2) is the lack of a scope in between the request and session scope, the so-called conversation scope. This forced developers to hassle with hidden input elements, unnecessary DB queries and/or abusing the session scope whenever one want to retain the initial model data in the subsequent request in order to successfully process validations, conversions, model changes and action invocations in the more complex webapplications. The pain could be softened by adopting a 3rd party library which retains the necessary data in the subsequent request like MyFaces Tomahawk <t:saveState> component, JBoss Seam conversation scope and MyFaces Orchestra conversation framework.

Another disadvantage for HTML/CSS purists is that JSF uses the colon : as ID separator character to ensure uniqueness of the HTML element id in the generated HTML output, especially when a component is reused more than once in the view (templating, iterating components, etc). Because this is an illegal character in CSS identifiers, you would need to use the \ to escape the colon in CSS selectors, resulting in ugly and odd-looking selectors like #formId\:fieldId {} or even #formId\3A fieldId {}. See also How to use JSF generated HTML element ID with colon ":" in CSS selectors? However, if you're not a purist, read also By default, JSF generates unusable ids, which are incompatible with css part of web standards.

JSF 1也是如此。x没有随Ajax工具一起发布。并不是真正的技术劣势,但由于当时的Web 2.0炒作,它变成了功能劣势。Exadel很早就引入了Ajax4jsf,经过多年的深入开发,成为JBoss RichFaces组件库的核心部分。另外一个组件库也附带了内置Ajax功能,最著名的是ICEfaces。

在JSF 1.2生命周期的一半左右,引入了一种新的基于XML的视图技术:Facelets。这在JSP之上提供了巨大的优势,特别是在模板方面。

JSF 2.0(2009 年 6 月)

这是第二个主要的发行版,Ajax是流行词汇。有很多技术和功能上的变化。JSP被Facelets取代,成为默认的视图技术,而Facelets被扩展为使用纯XML创建自定义组件(所谓的复合组件)的功能。另见为什么从JSF2.0开始,Facelets比JSP更受欢迎作为视图定义语言?

Ajax powers were introduced in flavor of the <f:ajax> component which has much similarities with Ajax4jsf. Annotations and convention-over-configuration enhancements were introduced to kill the verbose faces-config.xml file as much as possible. Also, the default naming container ID separator character : became configurable, so HTML/CSS purists could breathe relieved. All you need to do is to define it as init-param in web.xml with the name javax.faces.SEPARATOR_CHAR and ensuring that you aren't using the character yourself anywhere in client ID's, such as -.

Last but not least, a new scope was introduced, the view scope. It eliminated another major JSF 1.x disadvantage as described before. You just declare the bean @ViewScoped to enable the conversation scope without hassling all ways to retain the data in subsequent (conversational) requests. A @ViewScoped bean will live as long as you're subsequently submitting and navigating to the same view (independently of the opened browser tab/window!), either synchronously or asynchronously (Ajax). See also Difference between View and Request scope in managed beans and How to choose the right bean scope?

Although practically all disadvantages of JSF 1.x were eliminated, there are JSF 2.0 specific bugs which might become a showstopper. The @ViewScoped fails in tag handlers due to a chicken-egg issue in partial state saving. This is fixed in JSF 2.2 and backported in Mojarra 2.1.18. Also passing custom attributes like the HTML5 data-xxx is not supported. This is fixed in JSF 2.2 by new passthrough elements/attributes feature. Further the JSF implementation Mojarra has its own set of issues. Relatively a lot of them are related to the sometimes unintuitive behaviour of <ui:repeat>, the new partial state saving implementation and the poorly implemented flash scope. Most of them are fixed in a Mojarra 2.2.x version.

大约在JSF 2.0时代,引入了基于jQuery和jQuery UI的PrimeFaces。它成为了最流行的JSF组件库。

JSF 2.2(2013 年 5 月)

随着JSF 2.2的引入,HTML5成为了流行词,尽管技术上它只在所有较旧的JSF版本中得到支持。请参见JavaServer Faces 2.2和HTML5支持,为什么XHTML仍然被使用。JSF 2.2最重要的新特性是支持自定义组件属性,从而打开了一个可能性的世界,比如自定义无表单选按钮组。

除了特定于实现的错误和一些“恼人的小问题”,比如无法在验证器/转换器中注入EJB(在JSF 2.3中已经修复了),JSF 2.2规范中并没有真正的主要缺点。

基于组件的MVC vs基于请求的MVC

Some may opt that the major disadvantage of JSF is that it allows very little fine-grained control over the generated HTML/CSS/JS. That's not JSF's own, that's just because it's a component based MVC framework, not a request (action) based MVC framework. If a high degree of controlling the HTML/CSS/JS is your major requirement when considering a MVC framework, then you should already not be looking at a component based MVC framework, but at a request based MVC framework like Spring MVC. You only need to take into account that you'll have to write all that HTML/CSS/JS boilerplate yourself. See also Difference between Request MVC and Component MVC.

参见:

JSF、Servlet和JSP之间的区别是什么?(只是为了了解基础知识) 使用JSF开发无表CSS布局(关于JSF的另一个误区) JSF vs纯HTML/CSS/JS/jQuery(当JSF是错误的选择时) web应用程序中的设计模式(说明MVC背后的思想)


“JSF将输出视图层HTML和JavaScript,如果不进入控制器代码,您就无法控制或更改它们。”

实际上,JSF为您提供了灵活性,您既可以使用标准/第三方组件,也可以创建自己的组件,您可以完全控制呈现的内容。使用JSF 2.0创建自定义组件只需要一个xhtml。


我想到了一些缺点:

JSF is a component-based framework. This has inherent restrictions that have to do with obeying the component-model. AFAIK JSF supports only POST, so if you want a GET somewhere you have to do a plain servlet/JSP. Most components try to provide abstractions over domains like relational databases and front-end JavaScript, and many time these abstractions are "leaky" and very hard to debug. These abstractions might be a good starting point for a junior developer or someone not comfortable with a particular domain (e.g. front-end JavaScript), but are very hard to optimise for performance, since there are several layers involved, and most people that use them have little understanding of what is going on under the hood. The templating mechanisms that are usually used with JSF have nothing to do with how web desigers work. The WYSIWYG editors for JSF are primitive and in any case, your designer will give you HTML/CSS that you'll have to spend ages converting. Things like EL expressions are not statically checked and both the compiler and IDEs are not doing a good job at finding errors, so you'll end up with errors that you'll have to catch at run-time. This might be fine for dynamically typed language like Ruby or PHP, but if I have to withstand the sheer bloat of the Java ecosystem, I demand typing for my templates.

总而言之:使用JSF节省的时间,从避免编写JSP/servlet/bean样板代码,您将花费10倍的时间来使其可伸缩并完全按照您的要求进行操作。


对我来说,JSF 2.0最大的缺点不仅是JSF的学习曲线,而且是为了让它做有用的工作而必须使用的组件库。想想你要真正精通需要处理的数量惊人的规范和标准:

HTML in the various incarnations. Don't pretend you don't need to know it. HTTP -- when you can't figure out what is going on you have to open Firebug and see. For that you need to know this. CSS -- Like it or not. It isn't so bad really and there are some nice tools out there at least. XML -- JSF will probably the first place you use namespaces to this degree. Servlet Specification. Sooner or later you will get into calling methods in this package. Aside from that you have to know how your Facelets gets turned into XHTML or whatever. JSP (mostly so you know why you don't need it in JSF) JSTL (again, mostly to cope with legacy framework) Expression Language (EL) in its various forms. ECMAScript, JavaScript, or whatever else you want to call it. JSON -- you should know this even if you don't use it. AJAX. I would say JSF 2.0 does a decent job of hiding this from you but you still need to know what is going on. The DOM. And how a browser uses it. See ECMAScript. DOM Events -- a topic all by itself. Java Persistence Architecture (JPA) that is if you want your app to have any back end data base. Java itself. JSEE while you are at it. The Context Dependency Injection specification (CDI) and how it clashes with and is used with JSF 2.0 JQuery -- I would like to see you get along without it.

现在,一旦你完成了这些,你就可以继续使用专有规范,即你将在此过程中获得的组件库和提供者库:

PrimeFaces(我选择的组件库) RichFaces MyFaces ICEFaces EclipseLink(我的JPA提供者) Hibernate 焊接

别忘了容器!所有这些配置文件:

GlassFish(2,3等) JBoss Tomcat

那么——这让事情变得简单了吗?当然,JSF 2.0很“简单”,只要你想做的只是最基本的web页面和最简单的交互。

简单地说,JSF 2.0是当今软件界所存在的最复杂和最麻烦的技术大杂烩。我想不出还有什么更好的方法。


For me the biggest shortcoming of JSF is poor support for programmatically (dynamically) generated pages. If you want to construct your page (create page component model) dynamically from java code. For example if you are working on WYSIWYG web page constructor. Adequate documentation of this use case in not generally available. There are many points where you have to experiment and development is quiet slow. Many things just don't work how you would expect. But generally its possible hack it somehow. Good thing is that it's not problem in philosophy or architecture of JSF. It's simply not elaborated enough (as far as I know).

JSF 2带来了组合组件,这将使组件开发变得容易,但是它们对动态(编程式)构造的支持非常差。如果你克服了动态组合组件构造的复杂且几乎没有文档的过程,你会发现如果你把几个组合组件嵌套得稍微深一点,它们就会停止工作,抛出一些异常。

但是JSF社区似乎意识到了这个缺点。你可以从这两个bug中看到,他们正在研究这个 http://java.net/jira/browse/JAVASERVERFACES-1309 http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-599

至少在谈论规范时,JSF 2.2的情况会更好。


JSF只有一个缺点:在开始“JSF”开发之前,你应该清楚地了解web开发、核心java和前端架构。

现在“新的”JavaScript框架只是试图复制/粘贴“JSF”基于组件的模型。


在所有的“主流”框架中,如Spring MVC、Wicket、Tapestry等,Java EE的JSF及其复合组件是所提供的最精细的表示层和面向组件的技术。与HybridJava提供的解决方案相比,它有点麻烦和不完整。


在使用JSF工作了5年之后,我认为我可以添加我的2分。

Two major JSF drawbacks: Big learning curve. JSF is complex, that's just true. Its component nature. Component-based framework tries to hide the true nature of the Web, which comes with a huge amount of complications and disasters (like not supporting GET in JSF within almost 5 years). IMHO hiding HTTP Request/Response from the developer is an enormous mistake. From my experience, every component-based framework adds abstraction to the Web development, and that abstraction results in unnecessary overhead and higher complexity.

And minor drawbacks that come to my mind: By default ID of the object is composed of its parents' ids, for example form1:button1. No easy way to comment-out incorrect page's fragment. Tag <ui:remove> needs syntactically correct content which is parsed anyway. Low quality 3rd party components which e.g. don't check isRendered() inside processXxx() method before continuing. Incorporating LESS & Sencha is hard. Doesn't play well with REST. Not so easy for UX designers, because ready-to-use components have their own CSS styles, that need to be overwritten.

不要误会我的意思。作为一个组件框架,JSF在版本2中确实很好,但它仍然是基于组件的,而且永远是……

请看看Tapestry、Wicket的低人气以及有经验的JSF开发人员的低热情(这是更有意义的)。 作为对比,看看Rails、Grails、Django、Play!框架——它们都是基于动作的,不会试图向程序员隐藏真实的请求/响应和web的无状态特性。

对我来说,这是JSF的主要缺点。恕我直言,JSF可以适合某些类型的应用程序(内部网、表单密集型),但对于现实生活中的web应用程序来说,它不是一个好方法。

希望它能帮助一些人做出关于前端的选择。


我们使用JSF开发了一个示例项目(这是一个为期三周的研究,所以我们可能会丢失一些东西!)

我们尝试使用核心jsf,如果需要组件,我们使用PrimeFaces。

该项目是一个带有导航功能的网站。当点击菜单时,每个页面都应该通过ajax加载。

该网站有两个用例:

带有网格的页面。网格是通过ajax加载的,应该支持排序和分页 一个三步向导页面。每个页面都有客户端验证(用于简单验证)和服务器端ajax基础验证(用于复杂验证)。任何服务器异常(来自服务层)应该显示在向导的同一页上,而不需要导航到下一页。

我们发现:

You need to use some hacks from omniFaces to make the JSF view state fixed. The JSF state will be corrupted when you include pages via ajax in each other. This seems a bug in JSF and may be fixed on next releases (not in 2.3). The JSF Flow is not working correctly with ajax (or we could not make it work!) We try to use primeface wizard component instead but the client validation seems not supported and mean while it was not standard JSF flow standard. When using some jQuery components like jqGird, and you need to load JSON results, then you are advised to use pure servlet, The JSF will do nothing for you. So if you use these kind of components, your design will not fit in JSF. We try to do some client scripts when ajax complete by ajaxComplete and we found that the PF 4 has implemented its own ajax events. We had some jQuery components and we need to change their code.

如果您将上面的示例更改为非Ajax项目(或至少是较少的Ajax项目),您将不会面临上述许多问题。

我们将我们的研究总结为:

JSF在一个完全基于ajax的网站上不能很好地工作。

当然,我们发现JSF中有很多不错的特性,这些特性在某些项目中可能非常有用,所以请考虑您的项目需求。

请参考JSF技术文档来回顾JSF的优点,在我看来JSF最大的优点是来自@BalusC的完全和巨大的支持;-)


Inexperienced developers usually will create applications that are painfully slow and code will be really ugly and hard to maintain. Its deceptively simple to start, but actually requires some investment in learning if you want to write good programs. At least at the start you will often "stuck" on some problem and will spend more time reading balusc posts on internet than actually working :) After a while it will be less and less of that, but it still can be annoying. Even more annoying when you find out that the problem is not due to you lack of knowledge/mistake but actually a bug. Mojarra was(is?) quite buggy, and another layer of components adds even more problems. Richfaces was biggest piece of crap software ever written :) Don't know how it is now on version 4. We have Primefaces which is better, but still you will run into bugs or lack of features especially with more exotic components. And now you will need to pay for Primefaces updates. So I would say its buggy but its getting better especially after 2.2 version fixed some problems with spec. Framework getting more mature but still far from perfect (maybe myfaces better?). I don't find it especially flexible. Often if you need something very very customized and there are no components that does that - it will be a bit painful. Again I'm talking from average developer perspective - the one with deadlines, quick reading tutorials, and searching stackoverflow when getting stuck because no time to learn how it really works :) Often some components seems to have "almost" what you need, but not exactly and sometimes you might spend too much time to make it do something you want :) Need to be careful in evaluating if its better to create your own or torture existing component. Actually if you are creating something really unique I would not recommend JSF.

简而言之,我的缺点是:复杂,开发过程不流畅,漏洞百出,缺乏灵活性。

当然也有好处,但这不是你问的。不管怎样,这是我使用框架的经验,其他人可能有不同的意见,所以最好的方法是尝试一段时间,看看它是否适合你(只是一些更复杂的东西-不是天真的例子- JSF真的很出色:)依我看,JSF的最佳用例是业务应用程序,如crm等…


JSF有很多优点,关于缺点的问题,让我再补充一点。

在实现一个web项目的实际场景中,在一个时间框架内,你需要注意以下因素。

你的团队中是否有足够多的资深成员提出最好的建议 适合每个场景的控件? 你有足够的带宽来适应最初的学习曲线吗? 您的团队中是否有足够的专家来审查JSF 开发者制作的东西?

如果你对这些问题的回答是“不”,你可能会在不可维护的代码库中结束。


I'm not a Java Server Faces expert at all. But IMHO the main disadvantage is that it's server side. I'm tired of learning and using server side web presentation layer frameworks like ASP.NET Web Forms, ASP.NET MVC, Java Server Faces, Struts, php frameworks and ruby on rails frameworks. I said goodbye to all of them, and I said hello to Angularjs and TypeScript. My presentation layer runs on the browser. I doesn't matter if it is served by Windows IIS running php or ASP.NET, or if it is served by an Apache web server running on Linux. I just need to learn just one framework that works everywhere.

这只是我的个人意见。


评论我过去几个月的Primefaces/JSF体验:

如果你可以使用“现成的”组件,我想这并不可怕。 然而,当你走到外面并需要定制ui时,它就不能很好地发挥作用。-例如,我们需要在项目中使用Twitter的bootstrap。(不是primefaces bootstrap)。 现在我们的页面工作如下: 页面加载。 用户与具有ajax功能的Primefaces交互 Bootstrap的javascript绑定中断 我们运行额外的javascript来重新绑定所有内容

JSF避免编写javascript的承诺变成了编写比不使用Primefaces时更多的javascript——而javascript是用来修复Primefaces破坏的。

这是一个时间消耗器——除非你再次使用现成的东西。当不得不与Selenium一起工作时,也非常丑陋(Primefaces)。这些都是可以做到的,但是时间有限。

如果你和UX/设计团队一起工作,并且需要快速迭代UI,你可以通过学习jquery/编写直接的HTML来节省时间,或者查看react/angular。