You are on page 1of 25

Articles Category:

Java Programming Integrate Struts 2 JSF


1. JSF Introduction

JSF is the Sun, a new MVC proposed standards as part of standard JEE, and released together with the JDK, from a procedural point of view, JSF has already played out the traditional MVC framework, is very similar to ASP.NET Server component concept. Strictly speaking, JSF is not a framework but a specification, it is an important part of JEE5.0, page components by providing a way to hide the traditional HTTP Web application development details that allows developers to traditional desktop programmatically to develop Web applications, JSF background by Bean (and is equivalent to the controller) the properties, methods, components to bind directly to the page attribute or the action attribute value, can easily MVC to achieve system control. Struts2 provides good scalability, by means of the Struts2 JSF plugin, Struts2 and JSF integration can be achieved, once completed the integration of Struts2 and JSF, we can in the JSP page using Struts2 JSF page components, and with the Action the background to simulate the JSF Bean, JSP pages will be bound to the Action property of JSF components, allowing developers to JSF way to develop Struts2 applications. JSF is a specification, when the JSF specification proposed by Sun, but also provides a reference implementation of JSF (Reference Implementation, referred to as RI). Apache also provides another implementation of JSF, MyFaces is a framework, whether the current JSF RI or MyFaces framework, have gradually mature, fully realized projects as MVC framework. When, after Microsoft launched ASP.NET development platform, ASP.NET development platform includes a server component in the concept, through the use of server components, developers can develop desktop applications in a way to develop Web applications, but Web application program development and desktop application development, in essence, there are too many differences, Web application developers must deal with the details of HTTP, and Web application is a one page, each page of information is not continuous between the is stateless, but the essence of traditional desktop applications is continuously driven by a program other programs, because of some information between the various programs is continuous. And excellent Microsoft's ASP.NET simplifies Web application development In the ASP.NET server component, the developer can directly call the server component method to obtain the value of the server component ---- look beyond the traditional Web application request ---

response mode. The introduction of a large number of new JSF tag library, this tag library looks like a normal HTML tag, but it is not static, but dynamic. The mesh developers, use the JSF tag libraries and use HTML tag library work is not much difference between the JSF web developers do not need to ignore the dynamic part of the back-end labeling; web designers do not need to learn JAVA knowledge, even without access to this JSTL tag library, you can dynamically display the data. For application design personnel concerned, JavaServer Faces provides a similar desktop application development model, we can use event-based programming model, rather than request --- response programming model, thus avoiding the problem appears HTTP details. From the previous description can be seen, JSF has a complete MVC framework is, JSF is the core of event-driven, similar to the earlier Visual Basic programming mode, you can click the button for the page events, change the contents of the input box event provides incident response procedures to implement Web application process. JSF components and the package label very high degree, many typical applications developers do not need to deal with the details of HTTP, the page will be automatically mapped to the operation of the background of the JavaBean, the processing logic of direct access to the back of the JavaBean (Back Bean also is the controller) interaction. In addition, JSF provides a component label (very similar to the ASP.NET server component of the concept), the package level is very high, and has a very simple programming model, JSF event model can be refined to form in each form field. JSF POJO as the controller directly, and can use any method to handle user requests. Relative to the Struts2, JSF has a significant advantage of rich component tags, these components provide labels an event-driven programming model, and we can greatly simplify application development. From the above we can see the contrast between Struts2 and JSF have their own advantages: Struts2 Web programming is closer to the traditional process, using the more convenient. JSF component library to provide detailed event model, and simplify Web application development.

2. Using MyFaces
JSF RI generally considered more authoritative, is the official reference implementation, but too old-fashioned, rich enough to provide a component library; MyFaces JSF RI in the full realization of the basic functions, but also provides many additional component library, and therefore actual development is very attractive. So I'm using MyFaces.

Download and install the MyFaces 2.1


MyFaces JSF RI in addition to achieving the basic function, but also contains a tomahawk additional library; the database contains more components, by means of tomahawk's help, to provide more page components.

MyFaces please download and install the following steps:1. Download the required core class library MyFaces, landing http://myfaces.apache.org/download.html page, download the latest version of MyFaces, I use the MyFaces Core 1.2.3 Distribution, If you need additional labels tomahawk library, you have to download the tomahawk parts. tomahawk of the download links can be found on this page. I downloaded the myfaces-core-1.2.3-bin.zip file 2. The downloaded file \ lib under all JAR files to the WEB-INF \ lib directory, then you can use in Web applications MyFaces framework. 3. In order to build MyFaces procedures recommended myfaces-api-1.2.3.jar to classpath in JDK environment variables; of course, you can use the ant tool. 4. Installed in the Web application tag library MyFaces, MyFaces tag library installation used by the Servlet container according to the different, there may be two approaches :-

For more than Servlet 2.4 specification supports Web container, we do not need to modify the web.xml file, if you want to use the MyFaces JSP tag library page, you can use directly in the JSP page, the following two lines to import the tag library MyFaces :<% @ Taglib uri = "http://java.sun.com/jsf/html" prefix = "h"%> <% @ Taglib uri = "http://java.sun.com/jsf/core" prefix = "f"%> This seems very strange, why do we import the tag library and not MyFaces JSF tag library? Familiar with the custom tag library specification to know, here defined tag library URI is specified URI, and implementation of content and not must be linked.

MyFaces tag library file is on the myfaces-impl-1.2.3.jar META-INF folder under the path, above the standard for the use of Servlet2.4 Web application automatically reads the JAR file in the TLD file, and to which the URI identifying information. If the Servlet specification using the earlier Web application, you should add the following in the web.xml file configuration snippet:<taglib> <taglib-uri> http://java.sun.com/jsf/html </ taglib-uri> <taglib-location> / WEB-INF/lib/myfaces-impl-1.2.3.jar </ tagliblocation> </ taglib> <taglib> <taglib-uri> http://java.sun.com/jsf/core </ taglib-uri> <taglib-location> / WEB-INF/lib/myfaces-impl-1.2.3.jar </ tagliblocation> </ taglib>

2.2 Start pages from the input


MyFaces have been added in front of the tag library definition, so the page can now be used in the JSP tag library MyFaces, and if you want to see the tag library for more information, see the next tlddoc MyFaces API documentation under the path. Here is an example of the page code: <% @ Page contentType = "text / html; charset = GBK"%> <% @ Taglib uri = "http://java.sun.com/jsf/html" prefix = "h"%> <% @ Taglib uri = "http://java.sun.com/jsf/core" prefix = "f"%> <! - The sentence of the messages bound to the classes of resource files under -> <f:loadBundle basename="messages" var="msg"/> <html> <head> <title> Login </ title> </ head> <body> <! - Start using JSF's view of the output -> <f:view> <h3> <! - The output file in the global resources of international information -> <h:outputText value="#{msg.loginHeader}"/> </ h3> <! - Err output login Bean class content attribute -> <b> <h:outputText value="#{login.err}"/> </ b> <h:form id="loginForm"> <h:outputText value="#{msg.namePrompt}"/> <! - The single line input box below the value bound to login Bean class name properties -> <h:inputText value="#{login.name}" /> <br> <h:outputText value="#{msg.passPrompt}"/> <h:inputText id="pass" value="#{login.pass}"/> <br> <! - The action will bind the button below to login Bean valid class method -> <h:commandButton action="#{login.valid}" value="#{msg.buttonTitle}" /> </ h: form> </ f: view>

</ body> </ html>

The code from the above page you can see, MyFaces has an input page no longer the traditional HTML page, it is almost entirely used to generate the page effect MyFaces tags, these tags correspond to one another MyFaces page components, and these pages component first generates the corresponding HTML tags. When using the MyFaces tag is no longer the traditional form specified for the action attribute, used to set the form submission URL, the page will be bound to the back of each form field method of Bean to view the page components and Bean implementation associated with the background. Http://localhost:8080/jsfqs/ in the browser view the page, you can see the effect of modifications of the HTML page, the page appear very simple, we generate the HTML by viewing the source code, find the table One of the code is very complex, and the form contains a hidden field, this hidden form field is usually the following code: <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="rO0ABXVyABNb..." /> Value above the value of hidden field is usually very long, but in our view is totally garbled, but that is the MyFaces implementation status of the client kept the key, MyFaces Web application state to solve the drawbacks of discontinuous, it will the client state through the hidden field in the form of saved, but developers need to deal with these details, thus offering a better package.

2.3 Configuring the Web application MyFaces


Front of the JSP page is no longer a traditional HTML page, the page of the form fields is directly bound to a backing Bean, because some cannot directly visit the page to see the normal results (no MyFaces framework for participation, business component cannot be achieved and the background binding Bean), to make MyFaces JSP page to handle each, below the FacesServlet MyFaces deployed in Web applications, the following configuration in the web.xml file configuration FacesServlet fragment : <! - Configuring MyFaces to FacesServlet -> <servlet> <servlet-name> Faces Servlet </ servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </ servlet-class> <load-on-startup> 1 </ load-on-startup> </ servlet> <! - Faces Servlet Mapping Configuration -> <servlet-mapping> <servlet-name> Faces Servlet </ servlet-name> <url-pattern> *. jsf </ url-pattern> </ servlet-mapping> From the above configuration fragments can be seen, all requests for JSF will be used as a suffix after the treatment FacesServlet, FacesServlet will be the JSP page form field with the background Bean's properties or methods associated with them. In addition, if needed MyFaces use multiple configuration files (used to configure the navigation rules and background Bean), then also need to file in the web.xml configuration file to specify the location of JSF, MyFaces recommended managed-bean (background Bean) and navigation-rules configured separately, so MyFaces usually have multiple profiles, multiple configuration files in English between the comma (,) separated in the configuration file is based on the javax.faces.CONFIG_FILES parameters ServletContext to find that in web.xml file to add the following paragraph : <! - Specify the path to the configuration file MyFaces -> <context-param> <param-name> javax.faces.CONFIG_FILES </ param-name> <! - Between a number of configuration files, separated -> <param-value> / WEB-INF/faces-config-beans.xml, / WEB-INF/faces-config-nav.xml </

param-value> </ context-param>

After the above steps, you should also specify the program state between pages should be stored where you can choose to save the client, you can also choose to save on the server side, configure the program where to save the state of completion by the following configuration snippet: <! - Configure the program state is saved MyFaces -> <context-param> <param-name> javax.faces.STATE_SAVING_METHOD </ param-name> <param-value> client </ param-value> </ context-param> Because the option to save the program state on the client, so that the form elements on the client adds a hidden field, the value of the hidden field is the program state.

2.4 Bean at background


From the role of point of view, the background is very similar to Struts2 Bean's Action, but a completely different mode of action, the Action for Struts2, the application be submitted through the form submission Struts2 of Action; but the background MyFaces Bean, the system directly to the MyFaces label bound to a backing Bean's property or method. The background of the application code Bean is as follows: package lee; public class LoginBean { private String name; private String pass; private String err; public void setName (String name) { this.name = name; } public String getName () { return this.name; } public void setPass (String pass) { this.pass = pass; } public String getPass () { return this.pass; } public void setErr (String err) { this.err = err; } public String getErr () { return this.err; } public String valid () { if (name.equals ("scott") & & pass.equals ("tiger")) { return "success"; }

setErr ("your user name and password does not match"); return "failure"; } }

Bean is completely above the background of a POJO, handling user requests valid method name can be arbitrary, as long as the method can return a string. Complete background Bean, you must also use a configuration file to configure the background Bean, Bean the background configuration MyFaces configuration files using the standard complete, the configuration of the background Bean code / WEB-INF/faces- config-beans.xml as follows: <? xml version = "1.0" encoding = "gb2312"?> <! DOCTYPE faces-config PUBLIC "- / / Sun Microsystems, Inc. / / DTD JavaServer Faces Config 1.1 / / EN" "Http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config> <! - Configure the user bean -> <managed-bean> <managed-bean-name> login </ managed-bean-name> <managed-bean-class> lee.LoginBean </ managed-bean-class> <! - Bean instance to set the effective range of the background -> <managed-bean-scope> request </ managed-bean-scope> </ managed-bean> </ faces-config>

Navigation rules defined in 2.5


MyFaces to navigation rules to determine the flow of resources, navigation rule specifies a page from the beginning to the submit button on the page as a logical view of the value binding, navigation rules define the logical view and physical view of the correspondence between resources . configuration file / WEB-INF/faces-config-nav.xml as follows: <? xml version = "1.0" encoding = "gb2312"?> <! DOCTYPE faces-config PUBLIC "- / / Sun Microsystems, Inc. / / DTD JavaServer Faces Config 1.1 / / EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config> <navigation-rule> <! - If the result of the implementation of inputname.jsp success, from the view page to view page inputname.jsp greeting.jsp -> <! - Navigation rules for the input page -> <from-view-id> / login.jsp </ from-view-id> <navigation-case> <from-outcome> success </ from-outcome> <to-view-id> / greeting.jsp </ to-view-id> </ navigation-case> <navigation-case> <from-outcome> failure </ from-outcome> <to-view-id> / login.jsp </ to-view-id> </ navigation-case> </ navigation-rule> </ faces-config> From the above analysis we can see, MyFaces page tag than the traditional form is submitted more flexible, in a traditional Web application, each form corresponds to an event is triggered when the form is submitted, submit events, while a single form field alone cannot trigger events (unless JavaScript technology). And allows each form field MyFaces separate trigger event,

MyFaces allows two types of form fields trigger event: 1. Value Changed: Detection of changes in the value of form fields, when the form field value is changed, the trigger event. 2. Action: form submission triggered events. MyFaces also includes IoC (dependency injection), and other premium content, introduced here as the integration of JSF and Struts2, because some of these executive summaries are not here for details. 3. The installation of JSF plug-in With JSF plugin support, Struts2 JSF page components can be used, and through the Action Simulation Struts2 JSF background Bean, also support the JSF page components bound to the Action property, thus simulating a JSF's MVC approach. JSF can plug the life cycle of each stage of conversion into the corresponding interceptor Struts2; JSF plug-in contains a jsfStack interceptor stack, the interceptor stack for the implementation of JSF life cycle, when the whole constitutes the implementation of the results, Action Returns a string that is the logical view of the constant. JSF plug JSF lifecycle into several named jsf interceptors and the Result, therefore, in order to use JSF plug-in, we have to jsfStack the interceptor stack to the original interceptor stack, and allows configuration of type jsf's Result.

JSF plug-in installed in the following steps: 1. In order to use Struts2 JSF application group (actually using the MyFaces components, as MyFaces is an implementation of JSF), MyFaces lib path must be of the entire JAR files are copied to the Web application's WEB-INF \ lib \ path. 2. The Struts2 framework lib path of the struts2-jsf-plugin-2.0.11.2.jar file to the Web application WEB-INF \ lib \ path. 3. Also need to modify the web.xml file, add the file MyFaces support, as previously configured in the web.xml file FacesServlet handles all requests to *. jsf at the end of this time should be changed to deal with all the *. action at the end of the request, requiring an increase in the web.xml file the following snippet: <! - JavaServer Faces Servlet Configuration, not used directly -> <servlet> <servlet-name> faces </ servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </ servlet-class> <load-on-startup> 1 </ load-on-startup> </servlet> <! - JavaServer Faces Servlet Mapping, not called directly -> <servlet-mapping> <servlet-name> faces </ servlet-name> <url-pattern> *. action </ url-pattern> </ servlet-mapping> 4. Modify struts.xml configuration file to load plug-in JSF jsfStack interceptor stack defined in order to simplify the configuration of the interceptor, in struts.xml configuration file to add the following snippet: <package name="jsf" extends="jsf-default"> <! - Re-define an interceptor stack -> <interceptors> <interceptor-stack name="jsfFullStack"> <interceptor-ref name="params" /> <interceptor-ref name="basicStack"/> <interceptor-ref name="jsfStack"/> </ interceptor-stack>

</ interceptors> <! - Will jsfFullStack interceptor stack defined as the system default interceptors -> <default-interceptor-ref name="jsfFullStack"/> </ package> This completes the installation of JSF plug-in, ready to use MyFaces page in the application component 4, the use of JSF plug-in

4.1. Implement the business logic components


this shows a JEE application, a separate business logic components, business logic components through the spring container to create and manage. On behalf of business logic components are as follows:

package lee.service;
import java.util .*; import lee.model.Book; public class BookService { private Set <Book> bookDb; public BookService () { bookDb = new HashSet <Book> (); bookDb.add (new Book (1, "Spring2.0 Collection," "a comprehensive introduction to Spring each knowledge point")); bookDb.add (new Book (2, "Lightweight J2EE enterprise applications real," "describes the actual business of the J2EE development process")); } public Set <Book> getAllBook () { return bookDb; } public Book getBookById (int id) { for (Book b: bookDb) { if (b.getId () == id) { return b; } } return null; } public void addBook (Book b) { bookDb.add (b); } }

To achieve the above business logic component, business logic components must be configured in the spring container, the container in the spring configuration to deploy business logic components are as follows: <? xml version = "1.0" encoding = "GBK"?> <! - Specify the Spring configuration file Schema Information -> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="bs" class="lee.service.BookService"/> </ beans> Spring container because of the above Action instance is not configured; we will be by way of automatic assembly into the Action business logic components that instance. Struts2 applications in order to use Spring framework, we should also install the Spring plug-in applications, the Struts2 framework lib path of the struts2-spring-plugin-2.0.11.2.jar file to the Web application WEB-INF \ lib \ path, you must also copy documents spring.jar Web applications WEB-INF \ lib \ path, should also be configured in the web.xml file is automatically loaded when the application starts Spring container.

Here is the application the web.xml file: <? xml version = "1.0" encoding = "UTF-8"?> <web-app id = "jsf" version = "2.4" xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/webapp_2_4.xsd"> <! - Defined the core of Struts 2 Filter -> <filter> <filter-name> struts </ filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </ filter-class> </ filter> <! - Defined the core of Struts 2 filter to block all requests -> <filter-mapping> <filter-name> struts </ filter-name> <url-pattern> / * </ url-pattern> </ filter-mapping> <! - Define a Listener, the Listener is created when the application starts spring container -> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </ listenerclass> </ listener> <! - Define a Listener, the Listener MyFaces load at startup in the application of the context -> <listener> <listener-class> org.apache.myfaces.webapp.StartupServletContextListener </ listenerclass> </ listener> <! - JavaServer Faces Servlet Configuration, not used directly -> <servlet> <servlet-name> faces </ servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </ servlet-class> <load-on-startup> 1 </ load-on-startup> </ servlet> <! - JavaServer Faces Servlet Mapping, not called directly -> <servlet-mapping> <servlet-name> faces </ servlet-name> <url-pattern> *. action </ url-pattern> </ servlet-mapping> </ web-app>

At this point, has completed the implementation of the application logic layer, leaving only the realization of the MVC.

4.2. MVC implementation


Action code is as follows:package lee.action; import com.opensymphony.xwork2.ActionSupport; import java.util .*; import lee.model.Book; import lee.service.BookService; public class BookAction extends ActionSupport { private Book currentBook; private int editId; private BookService bs; public void setBs (BookService bs) { this.bs = bs; } public void setCurrentBook (Book currentBook) { this.currentBook = currentBook; } public Book getCurrentBook () { / / If editId request parameter is not empty, not empty currentBook if (editId! = 0) { this.currentBook = bs.getBookById (editId); } else if (currentBook == null) { currentBook = new Book (); } return this.currentBook; } public void setEditId (int editId) { this.editId = editId; } public int getEditId () { return this.editId; }

public List <Book> getAllBook () { List <Book> result = new ArrayList <Book> (); for (Book b: bs.getAllBook ()) { result.add (b); } return result; } public String save () { bs.addBook (currentBook); return "list"; } }

Action is defined above; you must also configure the file in the struts.xml Action, the following configuration snippet: <package name="lee" extends="jsf"> <action name="list" class="lee.action.BookAction"> <result name="success" type="jsf"/> <action> <action name="edit" class="lee.action.BookAction"> <result name="success" type="jsf"/> <result name="list" type="redirect"> list.action </ result> </action> </package> Here's list Action's success under the logical view corresponding to a type jsf the Result, the Result will go to list.jsp page.

To list.jsp Book page lists all instances, we use JSF's <h:dataTable ...> page components, of course, not alone <h:dataTable ../> components, it is usually <h : column .../> components used, the following is list.jsp page code: <% @ Page language = "java" contentType = "text / html; charset = GBK"%> <% @ Taglib prefix = "f" uri = "http://java.sun.com/jsf/core"%> <% @ Taglib prefix = "h" uri = "http://java.sun.com/jsf/html"%> <html> <head> <title> Struts2 + MyFaces + Spring integration </ title> </ head> <body> <f:view> <h3> Struts2 + MyFaces + Spring integration </ h3> <h3> list of all books </ h3> <h:dataTable value="#{action.allBook}" var="b" style="text-align:center;width:500px" border="1"> <h:column> <f:facet name="header"> <h:outputText value=" ID" /> </f: facet> <h:outputLink value="edit.action"> <f:param name="editId" value="#{b.id}" /> <h:outputText value="#{b.id}" /> </ h: outputLink> </ h: column> <h:column> <f:facet name="header"> <h:outputText value="" /> </ f: facet> <h:outputText value="#{b.name}" /> </ h: column> <h:column> <f:facet name="header">

<h:outputText value="" /> </ f: facet> <h:outputText value="#{b.desc}" /> </ h: column> </ h: dataTable> <p> <h:outputLink value="edit.action"> <h:outputText value=""/> </ h: outputLink> </p> </f: view> </body> </html> Page file from the above can be seen, extensive use of the above pages page MyFaces components, for instance to access the properties of Action, MyFaces component allows reference to the page by action corresponding to Action. For example, to access the corresponding page Action in the allBook properties to adopt the following code fragment: # {Action.allBook} / / this is equivalent to access to Action instance getAllBook () method returns directly in the browser sends a request to the list.action will be able to see a list of page impressions. Can be seen that the dataTable page by using the MyFaces components, you can easily realize how the collection of data list display. Page components using MyFaces, you can also simplify the control of the page display, and analog JSF's MVC pattern.

5. Using JSP tag in the JSF

FreeMarker template to use in the JSP tag in the web.xml file must start JSPSupportServlet, that is easy to add the following in the web.xml configuration: <servlet> <servlet-name> JspSupportServlet </ servlet-name> <servlet-class> org.apache.struts2.views.JspSupportServlet </ servlet-class> <load-on-startup> 1 </ load-on-startup> </ Servlet> Then, you can use in the JSF template to import the tag library as follows : <# Assign page = JspTaglibs ["/ WEB-INF/sitemesh-page.tld"]> The use of JSP tags to use the page as follows : <@ Page.applyDecorator page = "/ link.html" name = "panel" />

6. The integration of JSF thinking


Introduced by the previous example, you can see the JSF and Struts2 integration of the whole process, once the plug through the integration of the MyFaces JSF framework, JSP pages can use in the general assembly of the MyFaces page, and the MVC model can achieve JEE MyFaces system. MyFaces integration framework exists the following advantages: 1. Allows the use of ordinary Struts2 JSF page components on the page. 2. Can use the Struts2 configuration file, without using JSF configuration files. 3. Retained the MyFaces framework features, the page can even be used in Struts2 MyFaces complex components. Through the above example, and not see more of the characteristics of MyFaces components, in fact, Struts2 integrates Dojo framework, the provision of a large number of page components, including the FishEye effect, the rich text editor, a variety of charts so, Struts2 page components to MyFaces whether the effects of the aid is very necessary?, of course, MyFaces page components include components for more than Dojo functionality is to support the background Bean binding, can directly MyFaces page Struts2 in Action components and bind, this is a way to simulate the development of desktop applications, in fact, Struts2 has provided enough functionality to support our Web application, in most cases do not need to integrate with the JSF, but can through this article, we can see Struts2 provides excellent integration of other
frameworks.

You might also like