1. Trang chủ
  2. » Công Nghệ Thông Tin

Mastering JavaServer™ Face phần 10 potx

42 284 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 42
Dung lượng 676,58 KB

Nội dung

logon.title=Simple Blogger logon.username=Username: logon.password=Password: logon.submit=Submit logon.header=Welcome to Simple Blogger. logon.instructions=Enter your username and password to <br> log into your blog. logon.error.userName=Valid username is 6 to 10 characters. (try “blogger”) logon.error.password=Valid password is 6 to 10 characters. (try “blogger”) logon.error.unsuccessful=Unauthorized user, please try again. # webLogEdit webLogEdit.title=Blogger webLogEdit.save=Save webLogEdit.clear=Clear webLogEdit.logout=Exit Listing 11.19 (continued) # JSF application.properties # special properties global.blogPath=c:\\temp\\ Listing 11.20 JSF application.properties after conversion to JSF. # logon.properties title=Simple Blogger username=Username: password=Password: submit=Submit header=Welcome to Simple Blogger. instructions=Enter your username and password to log into your blog. # error messages for the logon page usernameError=Valid username is 6 to 10 characters. (try “blogger”) passwordError=Valid password is 6 to 10 characters. (try “blogger”) unsuccessfulError=Unauthorized user, please try again. usernameRequired=Username Required passwordRequired=Password Required Listing 11.21 JSF logon.properties after conversion to JSF. Converting a Struts Application to JSF 415 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 415 # blogEditForm.properties title=Blogger save=Save clear=Clear logout=Exit edit=edit delete=delete Listing 11.22 JSF blogEditForm.properties after conversion to JSF. Modify the Logon.jsp file (see Listing 11.18) as shown in the following code to load the logon.properties resource bundle and specify a local page variable. <f:loadBundle basename=”form.bundles.logon” var=”bloggerBundle”/> Modify the WebLogEdit.jsp file as shown in the following code to load the blogEditForm.properties resource bundle and specify a local page variable. <f:loadBundle basename=”form.bundles.logon” var=”bloggerBundle”/> Remove Unnecessary JavaScript A consistent goal of JSF design is to keep programming out of the JSP pages. If the Struts application being converted contains JavaScript functions, evaluate them to see if they are still needed after the conversion to JSF. Remove them if possible. Surround JSF Tags with the View Tag In order to use JSF tags in a JSP, surround the JSP code that will use JSF tags with <f:view> and </f:view>. Modify Logon.jsp and WebLogEdit. jsp as shown in Listing 11.18, Step 3. Replace the Simple Tags In the SimpleBlogger example, replacing the Struts tags is fairly straightfor- ward. For simple tags, Struts to JSF conversion is easy. However, for more complex tags, the replacement might not be a 1 to 1 replacement. For example, the logic and nesting tags of Struts are not present in JSF. Replacing logic and nesting tags would require rethinking the design of the JSP. 416 Chapter 11 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 416 Instead of replacing all the tags in a single step, we recommend using an iterative approach. Do the easy ones first. For example, set up the form, replace the labels, text, and text areas. Save the navigation, validation, and error- handling areas until later. At the end of each iteration, test the basic structure. As shown in Listing 11.18, Step 5, begin replacing tags in the Logon.jsp and WebLogEdit.jsp files. Replace <html:form> with <h:form> and </html:form> with </h:form> tags. Continue replacing the struts tags with JSF tags. For example, replace <bean: message key=”WebLogEdit.title”/> with <h:outputTextvalue= ”#{bloggerBundle.title}”/>. Add Validation Attributes or Tags One of the biggest differences between the design of Struts and JSF is the vali- dation of user input. In Struts, the ActionForm subclasses are responsible for implementing a validate method that is automatically called by the Struts framework (if specified in the struts-config actionForward declara- tion). Errors are collected and then displayed back to the user if the set of errors is not empty. In JSF, input validation is managed by either validation tags that are included in the presentation layer or by using a validate attribute associated with input tags. It should be noted that other layers in the application are still responsible for validating their own inputs. But the goal of user input valida- tion is to try and catch errors before they descend the layers of the architecture. See Table 11.2 for a complete list of validations shipped in JSF from Sun Microsystems. In the Logon.jsp file, we could have added the standard validate- Length tag (as shown in the following code) to the username and password fields. However, the error messages generated from the core validation tags are standard and not customizable for a particular input tag. <h:inputText id=”username” required=”true” size=”10” maxlength=”10” value=”#{logonForm.username}”> <f:validateLength maximum=”10” minimum=”6”/> </h:inputText> In our SimpleBlogger conversion, we wanted to mimic the Struts imple- mentation where the error messages were customized. Instead of using the core standard validation tags and their generic error messages, we use the validator attribute for the inputText tag as shown in the following code. Converting a Struts Application to JSF 417 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 417 <h:inputText id=”username” value=”#{logonForm.username}” size=”10” maxlength=”10” validator=”#{logonForm.validateUsername}”/> Next we add validation methods to the LogonForm class to support the validator attribute (Listing 11.23). Validation methods must meet two requirements to work correctly in the JSF framework. First, the validation methods must take a FacesContext, a UIComponent, and an Object as parameters. Second, the validation methods should throw a Validator Exception if there is a validation error. In our LogonForm implementation we create all messages from the logon.properties resource bundle when an instance of LogonForm is created. // LogonForm.java public class LogonForm extends Object { private String username; private String password; private ResourceBundle bundle; private FacesMessage loginErrorMessage; private FacesMessage usernameErrorMessage; private FacesMessage passwordErrorMessage; private FacesMessage usernameRequiredMessage; private FacesMessage passwordRequiredMessage; public LogonForm() { initializeMessages(); } private void initializeMessages() { bundle = ResourceBundle.getBundle(“form.bundles.logon”); String message = bundle.getString(“unsuccessfulError”); loginErrorMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, message, null); message = bundle.getString(“usernameError”); usernameErrorMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, message, null); message = bundle.getString(“passwordError”); passwordErrorMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, message, null); message = bundle.getString(“usernameRequired”); usernameRequiredMessage = new FacesMessage( FacesMessage.SEVERITY_INFO, message, null); message = bundle.getString(“passwordRequired”); passwordRequiredMessage = new FacesMessage( Listing 11.23 LogonForm.java validation methods. 418 Chapter 11 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 418 FacesMessage.SEVERITY_INFO, message, null); } /* Validation Methods */ public void validateUsername(FacesContext context, UIComponent toValidate, Object value) throws ValidatorException { int max = 10; int min = 6; String name = (String) value; int length = name.length(); if(length < min || length > max) { throw new ValidatorException(usernameErrorMessage); } return; // validation passed } public void validatePassword(FacesContext context, UIComponent toValidate, Object value) throws ValidatorException { int max = 10; int min = 6; String name = (String) value; int length = name.length(); if(length < min || length > max) { throw new ValidatorException(passwordErrorMessage); } return; // validation passed } Listing 11.23 (continued) To finish the validation changes for the SimpleBlogger, we need to replace the Struts html:errors tag in Logon.jsp (see Listing 11.18) with the JSF h:messages tag as shown in the following code. The layout=”table” attribute automatically formats multiple errors as rows in a table. <h:messages showSummary=”true” showDetail=”false” layout=”table”/> Replace Navigation Tags Replace navigation tags, like buttons and hypertext links, iteratively while building the navigation model and action classes, as described later in this chapter. The basic process is to define the navigation model, add support for actions, replace the navigation tag, and test. Using an iterative approach is best. Converting a Struts Application to JSF 419 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 419 Build the Navigation Model Both Struts and JSF externalize navigation into configuration files—struts- config.xml and faces-config.xml, respectively. The logic behind this design is to simplify page flow modifications for an application. For the SimpleBlogger application, we start with the UML state diagram from the analysis phase of our project, shown in Figure 11.4, to help us define our navigation requirements. We can simplify this diagram if we focus on event outcomes with respect to navigation, as shown in Figure 11.7. In this dia- gram, the literal events are generalized into success or failure. The net result of this effort is to minimize the number of navigation rules required. We could have defined a separate rule for every literal event, but many of the rules would only differ by name. To define navigation in JSF, use the navigation-case with from- outcome and to-view-id tags, as shown in Listing 11.24 below. <! faces-config.xml > <! Navigation rules > <navigation-rule> <from-view-id>/Logon.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/WebLogEdit.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/Logon.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/WebLogEdit.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/WebLogEdit.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/WebLogEdit.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Logon.jsp</to-view-id> </navigation-case> </navigation-rule> Listing 11.24 faces-config.xml navigation rules. 420 Chapter 11 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 420 Figure 11.7 SimpleBlogger generalized navigation state diagram. Add the Action Handlers Now it is time to wire the application together using our navigation rules and define methods to handle the application actions. In JSF, application actions are generated from UICommand components such as HtmlCommandButton or HtmlCommandLink, which implement the javax.faces.component.ActionSource interface. The application designer can use either the action or actionListener attributes of the associated UICommand component tags to specify how actions will be handled. Two examples of using the action attribute are demonstrated below. In the first case, the actual from-outcome name is specified, for example, action= ”success”. Navigation is transferred to the to-view-id as specified in the faces-config.xml navigation rule (see Listing 11.24). In the second case, the action attribute delegates control to the bean and method, logon form.logon, that will process, make decisions, and route the final naviga- tion. This logon bean method is responsible for handling any specific applica- tion action processing and returning the name of a from-outcome as specified in the faces-config.xml (see the logon method in Listing 11.25). // case 1: <h:commandButton value=”#{bloggerBundle.submit}” action=”success” /> // case 2: <h:commandButton value=”#{bloggerBundle.submit}” action=”#{logonform.logon}” /> We use the second case in our implementation of the JSF SimpleBlogger. The basic logic from the Struts LogonAction.execute() method is replicated in our JSF version. The logon() method validates the user with the Security Manager. If it is a valid user, then it stores the key/value pair for username in the Session scope and returns “success.” If the result is invalid, then it returns “failure.” failure success logout Log on Blog Edit failure success Converting a Struts Application to JSF 421 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 421 // LogonForm.java import javax.faces.context.FacesContext; import javax.faces.component.UIInput; import javax.faces.application.FacesMessage; import java.util.ResourceBundle; import java.util.Map; import domain.SecurityManager; public class LogonForm extends Object { public String logon() { SecurityManager security = new SecurityManager(); FacesContext facesContext = FacesContext.getCurrentInstance(); boolean hasErrorMessages = false; validateRequiredFields(); hasErrorMessages = facesContext.getMessages().hasNext(); // test for valid user boolean valid = security.isValidUser(getUsername(), getPassword()); if (!hasErrorMessages && valid) { Map sessionMap = facesContext.getExternalContext(). getSessionMap(); sessionMap.put(“username”, getUsername()); return “success”; } else if(hasErrorMessages==false) facesContext.addMessage(null, loginErrorMessage); return “failure”; } protected boolean validateRequiredFields() { boolean missingField = false; FacesContext facesContext = FacesContext.getCurrentInstance(); if(username!=null && username.length()<=0) { facesContext.addMessage(null, usernameRequiredMessage); missingField = true; } if(password!=null && password.length()<=0) { facesContext.addMessage(null, passwordRequiredMessage); missingField = true; } Listing 11.25 LogonForm.java with added methods for logon Actions. 422 Chapter 11 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 422 if(missingField) { return false; } return true; } Listing 11.25 (continued) In the Logon.jsp, replace the Struts submit Action: <html:submit><bean:message key=”logon.submit”/></html:submit> with the JSF actionCommand:<h:commandButton value=”#{bloggerBundle.submit}” action=”#{logonForm.logon}” /> Build and test the navigation and logon Action implementation. At this point in the conversion, the user should be able to launch the application, enter a valid username and password, and navigate to the BlogEdit page. Converting the Blog Edit Actions involves the same basic steps as the logon Action. Add support for edit, save, and delete Actions. In addition, we need to load an existing blog when the BlogEditForm is first loaded (see Listing 11.26). // BlogEditForm.java package form; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.ResourceBundle; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.faces.component.UIData; import domain.BlogEntry; import domain.BlogManager; public class BlogEditForm extends Object { private String currentMessage; private String currentTimestamp; private ArrayList blogEntries; private BlogManager blogManager; Listing 11.26 BlogEditForm.java action methods for save, edit, and delete. (continued) Converting a Struts Application to JSF 423 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 423 public BlogEditForm() { initialize(); refreshForm(); } protected void initialize() { FacesContext context = FacesContext.getCurrentInstance(); Map sessionMap = FacesContext.getCurrentInstance(). getExternalContext().getSessionMap(); String username = (String)sessionMap.get(“username”); ResourceBundle bundle = ResourceBundle.getBundle( “form.bundles.application”); String blogPath = bundle.getString(“global.blogPath”); blogManager = new BlogManager(username, blogPath); } protected void refreshForm() { try { setBlogEntries(blogManager.getBlogEntries()); } catch (IOException e) { System.out.println(“Refresh Error: Blog File Not Found”); e.printStackTrace(); } setCurrentMessage(“”); setCurrentTimestamp(“”); } public String save() { try { blogManager.saveBlogEntry(getCurrentTimestamp(), getCurrentMessage()); } catch (IOException e) { System.out.println(“Save failed”); e.printStackTrace(); return “failure”; } refreshForm(); return “success”; } public void edit(ActionEvent event) { // 1st parent is a Column, 2nd is the table UIData table = (UIData)event.getComponent().getParent().getParent(); BlogEntry selection = (BlogEntry)table.getRowData(); if (selection != null) { setCurrentMessage(selection.getMessage()); setCurrentTimestamp(selection.getDateAsString()); Listing 11.26 (continued) 424 Chapter 11 17_462071 Ch11.qxd 5/18/04 8:37 AM Page 424 [...]... described, 20 encoding, 103 , 278–279 Faces request, non-Faces response scenario, 84–85 initial JSF request, 160–165 JSP integration in JSF and, 160–167 non-Faces request, Faces response scenario, 83–84 overview, 101 103 renderResponse() method and, 88 sequence diagram, 165 skipping to, 88, 96, 98, 99, 100 , 101 subsequent JSF requests, 166–167 view handlers, 102 element (facesconfig.xml file),... username/password validation, 328 external context, FacesContext and, 87 F f prefix for core library, 157 for tags, 182 Faces Console, 152–153 Faces request defined, 83 Faces response generated by, 83 non-Faces response generated by, 84–85 Faces response defined, 83 generated by Faces request, 83 generated by non-Faces request, 83–84 element (facesconfig.xml file) child element,... 148–150 requirement for, 119 element, 128, 150–151 FacesContext class component tree, 86–87 described, 85–86 external context, 87 flow control, 88 getting the current instance, 86 localization, 88–90 message queue, 90–93 FacesEvent base class, 73 FacesListener interface, 74 FacesServlet controller, 20, 37, 115–116 facet tag, 208 facets Component application, 57–60 defined, 56, 209 Index methods... 93–95 Faces request defined, 83 Faces response defined, 83 FacesContext and, 85–93 flow control, 88 non-Faces request defined, 83 non-Faces response defined, 83 overview, 20, 81–82 phase identifiers, 75 scenarios, 83–85 steps in, 20 tree identifiers and request URIs, 97 required fields validation, 298 resources required for JSF, 117–118 for Web applications, 110 responseComplete() method, 88, 100 ... overview, 98 100 processValidators() method and, 99 renderResponse() method called in, 100 responseComplete() method and, 100 setValid() method and, 99 validate() method and, 98, 99, 100 , 202 processAction() method for Action events, 74 creating a listener, 262 defined by ActionListener interface, 204 means of determining action outcomes, 242 Search page example, 232, 234 processApplication() method, 101 processDecodes()... resources Ant tool, 153 Faces Console, 152 faces-config.xml file DTD, 123 JSF Reference Implementation, 108 servlet specification, 110 Tomcat, 108 Web site for this book, 431–432 web.xml file DTD, 113 invalidateCache() method, 273 InvoiceActionListener.java program, 206–207 InvoiceBean class accessing from AccountBean class, 195 check box setup, 220 implementing Comparator interface, 250–252 Modify Invoice... JSF, 420–421 for FacesServlet, 22–23 element (facesconfig.xml file), 128, 143–147 Search page example, 235, 243 simple example, 229 specifying, 229–230 element (facesconfig.xml file), 143, 145–147 NavigationHandler, 224, 234–235 element (facesconfig.xml file), 128, 143–147 See also navigation rules non-Faces request defined, 83 Faces response generated... 83–84 non-Faces response generated by, 85 non-Faces response defined, 83 generated by Faces request, 84–85 generated by non-Faces request, 85 Number Converter, 72–73 NumberConverter class inflexibility of, 280–281, 290 NumberFormat class and, 199 specifying Converter in inputText tag, 199, 200, 280–281 NumberFormat class, 199 NumberFormatException, 198 O object graphs See views Observer interface, 39... setup, 218–219 source code, 178–179 value binding, 180, 190–197 ViewInvoicesPage class and, 210 Invoke Application phase of life cycle ActionListener interface and, 224 component tree replacement in, 86 custom components and, 357 Index described, 20 event queues and, 93 overview, 101 processApplication() method and, 101 invoke() method, 232–233 isValidProductCode() method, 289 J JAR files See also specific... 139–140 element (facesconfig.xml file), 139, 140–142 element (facesconfig.xml file), 141, 142 mapping request URLs to FacesServlet controller, 115–116 Index McClanahan, Craig (Struts author), 383 Menu Renderer, 80 message queue of FacesContext, 90–91 message tags, 202 element (facesconfig.xml file), 130–131 messages tag, 202, 276, 289, 300 method binding expression, . bundle; private FacesMessage loginErrorMessage; private FacesMessage usernameErrorMessage; private FacesMessage passwordErrorMessage; private FacesMessage usernameRequiredMessage; private FacesMessage. 8:37 AM Page 421 // LogonForm.java import javax.faces.context.FacesContext; import javax.faces.component.UIInput; import javax.faces.application.FacesMessage; import java.util.ResourceBundle; import. bundle.getString(“passwordError”); passwordErrorMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, message, null); message = bundle.getString(“usernameRequired”); usernameRequiredMessage = new FacesMessage( FacesMessage.SEVERITY_INFO,

Ngày đăng: 14/08/2014, 09:22

TỪ KHÓA LIÊN QUAN