[prev in list] [next in list] [prev in thread] [next in thread]
List: struts-user
Subject: Re: struts-faces
From: Adam Hardy <ahardy.struts () cyberspaceroad ! com>
Date: 2003-09-18 9:21:18
[Download RAW message or body]
That sounds highly promising. Thanks for the information. You
architecture gurus have obviously been busy.
Regards
Adam
On 09/17/2003 06:43 PM Craig R. McClanahan wrote:
> On Wed, 17 Sep 2003, Adam Hardy wrote:
>
>
>>Date: Wed, 17 Sep 2003 13:14:27 +0200
>>From: Adam Hardy <ahardy.struts@cyberspaceroad.com>
>>Reply-To: Struts Users Mailing List <struts-user@jakarta.apache.org>
>>To: Struts Users Mailing List <struts-user@jakarta.apache.org>
>>Subject: Re: struts-faces
>>
>>Hi Craig,
>>I remember a while ago in one of these architecture- theme emails you
>>discussed the OO nature of struts & it had been said that the
>>action-form class and the action class broke the OO encapsulation
>>principle, by having data in one and functionality in another. You said
>>if you were going to design struts again, you would probably address this.
>>
>>Does JSFaces bring these two closer together? Or is this an area where
>>Faces is not involved? I see you say that in a combination of struts &
>>Faces, you would still use actions and forms.
>>
>
>
> JavaServer Faces is designed to give you options to organize things either
> way. Here's one example of a logon form (and associated back-end logic)
> that combines the Struts notions of ActionForm and Action into a single
> class (corresponds to the syntax in the EA4 release):
>
> JSP PAGE (/logon.jsp):
> =====================
>
> ...
> <h:form>
> <h:output_errors/>
> <h:panel_grid columns="2">
> <h:output_text value="Username:"/>
> <h:input_text id="username" valueRef="logonForm.username"/>
> <h:output_text value="Password:"/>
> <h:input_secret id="password" valueRef="logonForm.password"/>
> <h:command_button label="Log On" type="submit"
> actionRef="logonForm.logon"/>
> <h:command_button label="Reset" type="reset"/>
> </h:panel_grid>
> </h:form>
> ...
>
> FACES CONFIGURATION FILE (faces-config.xml):
> ===========================================
>
> ...
> <managed-bean>
> <managed-bean-name>logonForm</managed-bean-name>
> <managed-bean-class>mypackage.MyLogonForm</managed-bean-class>
> <managed-bean-scope>request</managed-bean-scope>
> </managed-bean>
> ...
> <navigation-rule>
> <from-tree-id>/logon.jsp</from-tree-id>
> <navigation-case>
> <from-outcome>success</from-outcome>
> <to-tree-id>/mainmenu.jsp</to-tree-id>
> </navigation-case>
> </navigation-rule>
> ...
>
> BACKING CLASS:
> =============
>
> package mypackage;
> public class MyLogonForm { // No required base class or interface
>
> // Property for "username" field
> private String username;
> public String getUsername() { return username; }
> public void setUsername(String username) { this.username = username; }
>
> // Property for "password" field
> private String password;
> public String getPassword() { return password; }
> public void setPassword(String password) { this.password = password; }
>
> // Return an Action for processing a logon
> public Action getLogon() {
> return new Action() {
> public String invoke() {
> return logon();
> }
> }
> }
>
> // The actual logon processing logic
> private String logon() {
> DAO dao = ...; // Data Access Object for user database
> User user = dao.findUser(this.username);
> if ((user != null) && password.equals(user.getPassword())) {
> ... record successful logon ...
> // Return logical outcome denoting success
> return ("success");
> } else {
> // Add an error message
> FacesContext.getCurrentInstance().addMessage(...);
> // Return logical outcome denoting "redisplay this page"
> return (null);
> }
> }
>
> }
>
> In this scenario, you can see that the form field values are stored in the
> same bean as the processing logic. Therefore, the processing logic can
> just use the field values directly (they are in the instance variables).
> However, it's only in the same class because the page author used
> "logonForm" at the beginning of the valueRef and actionRef expressions --
> they could just as easily have been stored in separate files.
>
> A couple of things not real obvious from this simple example, but
> interesting nevertheless:
>
> * The <managed-bean> declaration causes a new instance of the specified
> class to be created in (in this case) request scope, if it is not
> there already, similar to the way that Struts creates form beans for
> you as needed. However, JavaServer Faces generalizes this to happen
> automatically whenever it evaluates a reference expression and the
> first element does not identify an existing attribute in some scope.
> This can be very handy for instantiating "service" or "processor"
> objects whose precise characteristics are defined in the configuration
> file, rather than being coded in the page.
>
> * JavaServer Faces uses logical outcomes to manage navigation, similar
> to the way that Struts uses the returned ActionForward for this.
> The returned value is matched against a set of navigation rules that
> choose the next page to be displayed based on three criteria:
> - What page am I currently displaying? (Wildcard rules are allowed)
> - What action was performed? (You can have more than one submit button)
> - What logical outcome is returned?
> If no rule matches, the current page is redisplayed. I've adopted
> the convention in my code to return null as the logical outcome if
> this is what I want (i.e. the logon failure case here).
>
> * Struts encourages you to use Strings for field values that might
> need conversion, in order to redisplay correctly in case of conversion
> errors. You don't need to worry about that with JavaServer Faces,
> because the redisplay is handled by the components themselves. You
> will generally use the native data types for your field properties.
>
> * Programmers used to ASP.NET are familiar with the ability to
> programmatically interact with the actual user interface components
> themselves in code-behind files. It's very likely that this approach
> will also be accomodated in the final version of JavaServer Faces.
>
> The above example is likely to be typical if you're writing a new
> applicaton from scratch based on JavaServer Faces. But what if you've got
> an existing application based on Struts, and you just want to use
> JavaServer Faces to get the fancy UI widgets? That's where you would use
> the struts-faces integration library, because it lets you change just the
> JSP pages, and keep all your back end actions and form beans from before.
>
>
>>The reason I ask is that I just had a hard time redesigning a page
>>because my initial design failed. The page allows an edit of one parent
>>object, while showing a list of its child objects with
>>move-to-new-parent / delete controls. I got in a mess initially over
>>whether to use the parent or child's form and action for the child
>>operations.
>>
>
>
> In Struts, I would tend to model this sort of thing as a single form
> rather than two different forms.
>
> In JavaServer Faces, there will be a nice "editable table" or "data grid"
> type component that supports this type of use case.
>
>
>>Fortunately I solved it nicely by nesting the child objects in the
>>parent form, and passing the whole lot to the parent's model, which then
>>worked out if it needed to call the child's model for any operations.
>>
>
>
> Makes sense.
>
>
>>Adam
>>
>
>
> Craig
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: struts-user-help@jakarta.apache.org
>
>
--
struts 1.1 + tomcat 4.1.27 + java 1.4.2
Linux 2.4.20 RH9
---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic