JSF與Struts的異同

          JSFStruts的異同

          板橋里人 http://www.jdon.com 2005/09/05

            StrutsJSF/Tapestry都屬于表現(xiàn)層框架,這兩種分屬不同性質(zhì)的框架,后者是一種事件驅(qū)動(dòng)型的組件模型,而Struts只是單純的MVC模式框架,老外總是急吼吼說(shuō)事件驅(qū)動(dòng)型就比MVC模式框架好,何以見(jiàn)得,我們下面進(jìn)行詳細(xì)分析比較一下到底是怎么回事?

            首先事件是指從客戶端頁(yè)面(瀏覽器)由用戶操作觸發(fā)的事件,Struts使用Action來(lái)接受瀏覽器表單提交的事件,這里使用了Command模式,每個(gè)繼承Action的子類(lèi)都必須實(shí)現(xiàn)一個(gè)方法execute

            在struts中,實(shí)際是一個(gè)表單Form對(duì)應(yīng)一個(gè)Action類(lèi)(DispatchAction),換一句話說(shuō):在Struts中實(shí)際是一個(gè)表單只能對(duì)應(yīng)一個(gè)事件,struts這種事件方式稱(chēng)為application eventapplication eventcomponent event相比是一種粗粒度的事件。

            struts重要的表單對(duì)象ActionForm是一種對(duì)象,它代表了一種應(yīng)用,這個(gè)對(duì)象中至少包含幾個(gè)字段,這些字段是Jsp頁(yè)面表單中的input字段,因?yàn)橐粋€(gè)表單對(duì)應(yīng)一個(gè)事件,所以,當(dāng)我們需要將事件粒度細(xì)化到表單中這些字段時(shí),也就是說(shuō),一個(gè)字段對(duì)應(yīng)一個(gè)事件時(shí),單純使用Struts就不太可能,當(dāng)然通過(guò)結(jié)合JavaScript也是可以轉(zhuǎn)彎實(shí)現(xiàn)的。

            而這種情況使用JSF就可以方便實(shí)現(xiàn),

          <h:inputText id="userId" value="#{login.userId}">
            <f:valueChangeListener type="logindemo.UserLoginChanged" />
          </h:inputText>

            #{login.userId}表示從名為loginJavaBeangetUserId獲得的結(jié)果,這個(gè)功能使用struts也可以實(shí)現(xiàn),name="login" property="userId"

            關(guān)鍵是第二行,這里表示如果userId的值改變并且確定提交后,將觸發(fā)調(diào)用類(lèi)UserLoginChangedprocessValueChanged(...)方法。

            JSF可以為組件提供兩種事件:Value Changed Action. 前者我們已經(jīng)在上節(jié)見(jiàn)識(shí)過(guò)用處,后者就相當(dāng)于struts中表單提交Action機(jī)制,它的JSF寫(xiě)法如下:

          <h:commandButton id="login" commandName="login">
            <f:actionListener type=”logindemo.LoginActionListener” />
          </h:commandButton>

            從代碼可以看出,這兩種事件是通過(guò)Listerner這樣觀察者模式貼在具體組件字段上的,而Struts此類(lèi)事件是原始的一種表單提交Submit觸發(fā)機(jī)制。如果說(shuō)前者比較語(yǔ)言化(編程語(yǔ)言習(xí)慣做法類(lèi)似Swing編程);后者是屬于WEB化,因?yàn)樗莵?lái)自Html表單,如果你起步是從Perl/PHP開(kāi)始,反而容易接受Struts這種風(fēng)格。

          基本配置

            StrutsJSF都是一種框架,JSF必須需要兩種包JSF核心包、JSTL包(標(biāo)簽庫(kù)),此外,JSF還將使用到Apache項(xiàng)目的一些commons包,這些Apache包只要部署在你的服務(wù)器中既可。

            JSF包下載地址:http://java.sun.com/j2ee/javaserverfaces/download.html選擇其中Reference Implementation

            JSTL包下載在http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi

            所以,從JSF的驅(qū)動(dòng)包組成看,其開(kāi)源基因也占據(jù)很大的比重,JSF是一個(gè)SUN伙伴們工業(yè)標(biāo)準(zhǔn)和開(kāi)源之間的一個(gè)混血兒。

            上述兩個(gè)地址下載的jar合并在一起就是JSF所需要的全部驅(qū)動(dòng)包了。與Struts的驅(qū)動(dòng)包一樣,這些驅(qū)動(dòng)包必須位于Web項(xiàng)目的WEB-INF/lib,和Struts一樣的是也必須在web.xml中有如下配置:

          <web-app>
            <servlet>
              <servlet-name>Faces Servlet</servlet-name>
              <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
              <load-on-startup>1</load-on-startup>
            </servlet>

            <servlet-mapping>
              <servlet-name>Faces Servlet</servlet-name>
              <url-pattern>*.faces</url-pattern>
            </servlet-mapping>
          </web-app>

            這里和Strutsweb.xml配置何其相似,簡(jiǎn)直一模一樣。

            正如Strutsstruts-config.xml一樣,JSF也有類(lèi)似的faces-config.xml配置文件:


          <faces-config>
            <navigation-rule>
              <from-view-id>/index.jsp</from-view-id>
              <navigation-case>
                <from-outcome>login</from-outcome>
                <to-view-id>/welcome.jsp</to-view-id>
              </navigation-case>
            </navigation-rule>

            <managed-bean>
              <managed-bean-name>user</managed-bean-name>
              <managed-bean-class>com.corejsf.UserBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
            </managed-bean>
          </faces-config>

           

            在Struts-config.xml中有ActionForm Action以及Jsp之間的流程關(guān)系,在faces-config.xml中,也有這樣的流程,我們具體解釋一下Navigation

            在index.jsp中有一個(gè)事件:

          <h:commandButton label="Login" action="login" />

            action的值必須匹配form-outcome值,上述Navigation配置表示:如果在index.jsp中有一個(gè)login事件,那么事件觸發(fā)后下一個(gè)頁(yè)面將是welcome.jsp

            JSF有一個(gè)獨(dú)立的事件發(fā)生和頁(yè)面導(dǎo)航的流程安排,這個(gè)思路比struts要非常清晰。

            managed-bean類(lèi)似StrutsActionForm,正如可以在struts-config.xml中定義ActionFormscope一樣,這里也定義了managed-beanscopesession

            但是如果你只以為JSFmanaged-bean就這點(diǎn)功能就錯(cuò)了,JSF融入了新的Ioc模式/依賴(lài)性注射等技術(shù)。

          Ioc模式

            對(duì)于Userbean這樣一個(gè)managed-bean,其代碼如下:

          public class UserBean {
            private String name;
            private String password;

            // PROPERTY: name
            public String getName() { return name; }
            public void setName(String newValue) { name = newValue; }

            // PROPERTY: password
            public String getPassword() { return password; }
            public void setPassword(String newValue) { password = newValue; }
          }

          <managed-bean>
            <managed-bean-name>user</managed-bean-name>
            <managed-bean-class>com.corejsf.UserBean</managed-bean-class>
            <managed-bean-scope>session</managed-bean-scope>

            <managed-property>
              <property-name>name</property-name>
              <value>me</value>
            </managed-property>

            <managed-property>
              <property-name>password</property-name>
              <value>secret</value>
            </managed-property>
          </managed-bean>

            faces-config.xml這段配置其實(shí)是將"me"賦值給name,將secret賦值給password,這是采取Ioc模式中的Setter注射方式

          Backing Beans

            對(duì)于一個(gè)web form,我們可以使用一個(gè)bean包含其涉及的所有組件,這個(gè)bean就稱(chēng)為Backing Bean Backing Bean的優(yōu)點(diǎn)是:一個(gè)單個(gè)類(lèi)可以封裝相關(guān)一系列功能的數(shù)據(jù)和邏輯。

            說(shuō)白了,就是一個(gè)Javabean里包含其他Javabean,互相調(diào)用,屬于Facade模式或Adapter模式。


            對(duì)于一個(gè)Backing Beans來(lái)說(shuō),其中包含了幾個(gè)managed-beanmanaged-bean一定是有scope的,那么這其中的幾個(gè)managed-beans如何配置它們的scope呢?

          <managed-bean>
            ...
            <managed-property>
              <property-name>visit</property-name>
              <value>#{sessionScope.visit}</value>
            </managed-property>

            這里配置了一個(gè)Backing Beans中有一個(gè)setVisit方法,將這個(gè)visit賦值為session中的visit,這樣以后在程序中我們只管訪問(wèn)visit對(duì)象,從中獲取我們希望的數(shù)據(jù)(如用戶登陸注冊(cè)信息),而visit是保存在session還是applicationrequest只需要配置既可。

          UI界面

            JSFStruts一樣,除了JavaBeans類(lèi)之外,還有頁(yè)面表現(xiàn)元素,都是是使用標(biāo)簽完成的,Struts也提供了struts-faces.tld標(biāo)簽庫(kù)向JSF過(guò)渡。

            使用Struts標(biāo)簽庫(kù)編程復(fù)雜頁(yè)面時(shí),一個(gè)最大問(wèn)題是會(huì)大量使用logic標(biāo)簽,這個(gè)logic如同if語(yǔ)句,一旦寫(xiě)起來(lái),搞的JSP頁(yè)面象俄羅斯方塊一樣,但是使用JSF標(biāo)簽就簡(jiǎn)潔優(yōu)美:

          <jia:navigatorItem name="inbox" label="InBox"
            icon="/images/inbox.gif"
            action="inbox"
            disabled="#{!authenticationBean.inboxAuthorized}"/>

            如果authenticationBeaninboxAuthorized返回是假,那么這一行標(biāo)簽就不用顯示,多干凈利索!

            先寫(xiě)到這里,我會(huì)繼續(xù)對(duì)JSF深入比較下去,如果研究過(guò)Jdon框架的人,可能會(huì)發(fā)現(xiàn),Jdon框架的jdonframework.xmlservice配置和managed-bean一樣都使用了依賴(lài)注射,看來(lái)對(duì)Javabean的依賴(lài)注射已經(jīng)迅速地成為一種新技術(shù)象征,如果你還不了解Ioc模式,趕緊補(bǔ)課。

           

           

           

           

           

           

           

           

           

           

           

           

           

          JavaServer Faces (JSF) vs Struts

          A brief comparison

          By: Roland Barcia

          My JSF article series and Meet the Experts appearance on IBM developerWorks received a lot of feedback.

          I would have to say, the most common question or feedback came along the lines of comparing Struts to JSF. I thought it would be a good idea to compare JSF to Struts by evaluating various features that an application architect would look for in a Web application framework. This article will compare specific features. Those on which I will focus include:

          ·    Maturity

          ·    Controller Flexibility/Event Handling

          ·    Navigation

          ·    Page development

          ·    Integration

          ·    Extensibility

          Certainly, there are other places in which you might want to do a comparison, such as performance, but I'll focus on the set I just mentioned. I'll also spend more time on the Controller and Navigation sections because they are the heart of the frameworks. Performance of JSF is specific to the vendor implementation, and I always encourage people to perform their own performance tests against their own set of requirements because there are too many factors that can affect performance. A performance evaluation would be unfair. Other areas such as page layout, validation, and exception handling were also left out in the interest of saving space.

          Maturity

          Struts has been around for a few years and has the edge on maturity. I know of several successful production systems that were built using the Struts framework. One example is the WebSphere Application Server Web-based administrative console. JavaServer Faces(JSF), however, has been in draft for 2 years. Several companies, including IBM as well as the creator of Struts, Craig McClanahan, have contributed to the creation of JSF during that time. Nonetheless, it will take some time to see a few systems deployed.

          Struts definitely has the edge in this category. With JSF, however, you can rely on different levels of support depending on which implementation you choose. For example, the JSF framework inside WebSphere Studio comes with IBM support.

          Controller Flexibility/Event Handling

          One of the major goals of Struts was to implement a framework that utilized Sun's Model 2 framework and reduced the common and often repetitive tasks in Servlet and JSP development. The heart of Struts is the Controller. Struts uses the Front Controller Pattern and Command Pattern. A single servlet takes a request, translates HTTP parameters into a Java ActionForm, and passes the ActionForm into a Struts Action class, which is a command. The URI denotes which Action class to go to. The Struts framework has one single event handler for the HTTP request. Once the request is met, the Action returns the result back to the front controller, which then uses it to choose where to navigate next. The interaction is demonstrated in Figure 1.

          JSF uses the Page Controller Pattern. Although there is a single servlet every faces request goes through, the job of the servlet is to receive a faces page with components. It will then fire off events for each component and render the components using a render toolkit. The components can also be bound to data from the model. The faces life-cycle is illustrated in Figure 2.

          JSF is the winner in this area, because it adds many benefits of a front controller, but at the same time gives you the flexibility of the Page Controller. JSF can have several event handlers on a page while Struts is geared to one event per request. In addition, with Struts, your ActionForms have to extend Struts classes, creating another layer of tedious coding or bad design by forcing your model to be ActionForms. JSF, on the other hand, gives developers the ability to hook into the model without breaking layering. In other words, the model is still unaware of JSF.

          Navigation

          Navigation is a key feature of both Struts and JSF. Both frameworks have a declarative navigation model and define navigation using rules inside their XML configuration file. There are 2 types of navigation: static navigation - when one page flows directly to the next; and dynamic navigation - when some action or logic determines which page to go to.

          Both JSF and Struts currently support both types of navigation.

          Struts
          Struts uses the notion of forwards to define navigation. Based on some string, the Struts framework decides which JSP to forward to and render. You can define a forward by creating an Action as shown in the snippet below.

          <action path="/myForward" forward="/target.jsp"> </action>

          Struts supports dynamic forwarding by defining a forward specifically on an Action definition. Struts allows an Action to have multiple forwards.

           
          <action-mappings>
                       <action name="myForm" path="/myACtion" scope="request"
                        type="strutsnav.actions.MyAction">
                              <forward name="success" path="./target.jsp">
                              </forward>
                              <forward name="error" path="./error.jsp">
                              </forward>
           
                       </action>
               </action-mappings>

          Developers can then programmatically choose which forward to return.

           
          public ActionForward execute(
                       ActionMapping mapping,
                       ActionForm form,
                       HttpServletRequest request,
                       HttpServletResponse response)
                       throws Exception {
           
                       ActionErrors errors = new ActionErrors();
                       ActionForward forward = new ActionForward(); // return value
                       MyForm myForm = (MyForm) form;
           
                       try {
           
                              // do something here
           
                       } catch (Exception e) {
           
                              // Report the error using the appropriate name and ID.
                              errors.add("name", new ActionError("id"));
                              forward = mapping.findForward("success");
                              return (forward);
                       }
           
                       forward = mapping.findForward("success");
                       return (forward);
           
               }

          JSF Static Navigation
          JSF supports navigation by defining navigation rules in the faces configuration file. The example below shows a navigation rule defining how one page goes to the next.

           
          <navigation-rule>
                       <from-view-id>/FromPage.jsp</from-view-id>
                       <navigation-case>
                              <from-outcome>success</from-outcome>
                              <to-view-id>/ToPage.jsp</to-view-id>
                       </navigation-case>
               </navigation-rule>

          However, unlike Struts, JSF navigation is applied on the page level and can be action-independent. The action is hard coded into the component allowing for finer grain control on the page. You can have various components on the page define different actions sharing the same navigation rule.

          <hx:commandExButton type="submit" value="Submit"
          styleClass="commandExButton" id="button1" action="success" />

          JSF also supports dynamic navigation by allowing components go to an action handler.

          <hx:commandExButton type="submit" value="Submit"
          styleClass="commandExButton" id="button1" action="#
          {pc_FromPage.doButton1Action}" />

          Developers can then code action handlers on any class to make the dynamic navigation decision.

           
          public String doButton1Action() {
                       return "success";
               }

          Even though navigation rules don't need to specify the action in order to support dynamic navigation, JSF allows you to define the action on the navigation rule if you so choose. This allows you to force a specific navigation rule to go through an action.

           
          <navigation-rule>
                       <from-view-id>/FromPage.jsp</from-view-id>
                       <navigation-case>
                              <from-action>#{pc_FromPage.doButton1Action}</from-action>
                              <from-outcome>success</from-outcome>
                              <to-view-id>/ToPage.jsp</to-view-id>
                       </navigation-case>
               </navigation-rule>

          Both Struts and JSF are pretty flexible from a navigation stand point, but JSF allows for a more flexible approach and a better design because the navigation rule is decoupled from the Action. Struts forces you to hook into an action, either by a dummy URI or an action class. In addition, it is easier in JSF to have one page with various navigation rules without having to code a lot of if-else logic.

          Page Development

          JSF was built with a component model in mind to allow tool developers to support RAD development. Struts had no such vision. Although the Struts framework provides custom libraries to hook into Action Forms and offers some helper utilities, it is geared toward a JSP- and HTTP-centric approach. SF provides the ability to build components from a variety of view technologies and does it in such a way to be toolable. JSF, therefore, is the winner in this area.

          Integration

          Struts was designed to be model neutral, so there is no special hooks into a model layer. There are a view reflection-based copy utilities, but that's it. Usually, page data must be moved from an Action Form into another Model input format and requires manual coding. The ActionForm class, provides an extra layer of tedious coding and state transition.

          JSF, on the other hand, hides the details of any data inside the component tree. Rich components such as data grids can be bound to any Java class. This allows powerful RAD development, such as the combination of JSF and SDO. I will discuss this further in future articles.

          Extensibility

          Both Struts and JSF provides opportunities to extend the framework to meet expanding requirements. The main hook for Struts is a RequestProcessor class that has various callback methods throughout the life-cycle of a request. A developer can extend this class to replace or enhance the framework.

          JSF provides equivalent functionality by allowing you to extend special life-cycle interfaces. In addition, JSF totally decouples the render phase from the controller allowing developers to provide their own render toolkits for building custom components. This is one of the powerful features in JSF that Struts does not provide. JSF clearly has the advantage in this area.

          Conclusion

          In general, JSF is a much more flexible framework, but this is no accident. Struts is a sturdy framework and works well. JSF was actually able to learn a great deal from Struts projects. I see JSF becoming a dominant framework because of its flexible controller and navigation. Furthermore, JSF is built with integration and extensibility in mind. If you are starting a new project today, you'd have to consider many factors. If you have an aggressive schedule with not much time to deal with evaluating different vendors or dealing with support for new JSF implementations, Struts may be the way to go. But from a strategic direction and programming model, JSF should be the target of new applications. I encourage developers to take time to learn JSF and begin using them for new projects. In addition, I would consider choosing JSF vendors based on component set and RAD tools. JSF isn't easier than Struts when developing by hand, but using a RAD JSF tool like WebSphere Studio can greatly increase your productivity.

          posted on 2005-10-28 15:47 guyue 閱讀(303) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 邻水| 玛曲县| 桐梓县| 泸水县| 伊通| 大渡口区| 泰来县| 浦北县| 靖边县| 宝坻区| 溧阳市| 青田县| 吴川市| 河池市| 钟山县| 威海市| 新邵县| 崇义县| 介休市| 武川县| 红桥区| 南投市| 攀枝花市| 东阿县| 昔阳县| 柳江县| 桦南县| 福贡县| 万年县| 大理市| 舟山市| 石嘴山市| 樟树市| 涞源县| 溆浦县| 巴塘县| 娄烦县| 黄冈市| 筠连县| 忻城县| 南澳县|