Re: Recommendations for a web application framework?
- From: Timo Stamm <timo.stamm@xxxxxxxx>
- Date: Sun, 09 Jul 2006 00:21:59 +0200
Chris Smith schrieb:
Timo Stamm <timo.stamm@xxxxxxxx> wrote:In a different form, it's also the Wicket example you posted, which has two id attributes in the page corresponding to the two components; and then a Java class representing that page, which again has to match the id attributes on components on the page. It's a little better than Struts, to be sure. Yet I still see this duality wherein there's a Java class representing the form.Unfortunately, you can not eliminate this duality if you want to use HTML templates and insert a value into a specific position in the template.
I think it is avoidable, and I think JSF does it.
To be perhaps a little clearer, what JSF does is ensure that the correspondence between identifiers and names in Java code and HTML content is one-way. That eliminates the really painful bit, which is to try and keep stuff in sync.
Yes, JSF avoids the duality because it doesn't really have templates. You don't have to bind a component to a position in the template, you define components directly in the JSP code using taglibs, and this introduces problems:
- It is impossible to use HTML mockups from a web designer without major changes that render them useless to the web designer.
- Browser incompatibilies are annoying. Having to debug them on a running application instead of the actual HTML file makes the issue worse.
- It forces you to express logic in a XML language. Java may have a verbose syntax, but it's still much better than XML, especially with a decent IDE.
I can actually write a JSF backing bean that encapsulates what I need to know in order to perform some task... and I really don't care whether the user interface gathers that information (a) with one component or another; (b) with a single HTML page or in a wizard-style interface across several pages; etc. Instead, I create and publish my interface in the form of a backing bean, and then the web design can be done along those lines. Those changes to the user interface part of the application are performed simply by binding different JSF components to different backing bean properties. The backing beans only need to be changed if there's a real change, such as the need to enter additional information that the application doesn't know how to handle yet.
The equivalent in the wicket world is called a "model object". But you don't access it from the template, but from the java code. There has been support to do make model properties available via OGNL (roughly similar to the JSP EL), but the usage is discouraged and I don't even know if the feature is still available.
But with wicket, you could encapsulate the two components for the link and the output label into one component and you can use language features like inheritance to remove redundancy (yes, it works with HTML templates too because a HTML file is always associated with a java class).
It's exactly that -- an HTML file is always associated with a Java class -- that bothers me. I think that's a serious problem. My Java code shouldn't care what HTML files exist in the application.
That is exactly what I was thinking when I had a first look at Wicket. I am somewhat allergic to redundancy and was very dubious about the need to tell the framework twice that I want a component there. But in practice, it really isn't an issue because there are so many ways to remove the redundancy and it isn't really as bad as it looks.
For example, I would create a base page class for a project, that contains common elements like navigation and a footer. This page class would be extended by the actual pages. The subclasses only have to take care of their contribution, and they may not even need any associated HTML files, because the HTML template associated with the super class is reused.
The same can be applied to components. You do not need a HTML template for each and every component.
In practice, I spend very little time maintaining the HTML templates.
This is a major problem with JSF to me: You have to define a lot of classes and XML configuration files.
Hmm? In addition to the web application deployment descriptor, you have to add one XML file. I don't like XML for configuration too awfully much, but the actual information in that file is quite meaningful. It consists mainly of the navigation scheme between pages, and the model of information that is available to the pages. I actually wish these were in different files, since they express facts that are useful in different parts of the development process; but I imagine that didn't happen in order to avoid the issue of too many configuration files. In any case, you can still do things that way manually.
As for classes, I'm willing to wager that there are fewer classes involved in a JSF implementation of something that with anything that requires a Java class dual for each
Are you referring to the need to declare backing beans in
faces-config.xml? That would be the key to avoiding the need for the class per web page model, in that it allows the view layer to access whatever data it needs based on declared interfaces; and conversely, the model layer to look in well-defined places for information regardless of what HTML page it came from.
The example I gave requires one additional class to represent the Application and one entry in the deployment descriptor to get it running. An implementation in JSF would probably require at least twice as many files.
It would require:
1. WEB-INF/web.xml
2. WEB-INF/faces-config.xml
3. counter.jsp
4. WEB-INF/classes/.../CounterBean.java
Furthermore, none of these are really all that involved.
I stand corrected, you don't have to define twice as many files.
My memory might have played me a trick, because working with JSF sure felt like having to do at least twice as much work :)
web.xml would contain a mapping for the faces servlet,
Wicket requires the mapping for the wicket servlet, and the class name of the Application class.
and possibly some configuration if you want to change the defaults.
You configure Wicket applications in the Wicket application class.
faces-config.xml would contain one navigation rule
Not necessary. In Wicket, pages are plain Java objects and you can navigate with plain Java code:
setResponsePage(new MyPage());
If you really need to maintain navigation paths in an XML file, you can easily create you own method that looks the target up in an XML file. But I doubt that most real world application require this.
and one backing bean declaration for CounterBean.
Not necessary.
The counter.jsp file would contain the view code,
This would be equivalent to the CounterPage.java + CounterPage.html files of my example. Wicket needs one more file.
and would bind the components to CounterBean via EL expressions.
I don't need a CounterBean, just an int, but it has to be bound via OGNL (similar to EL).
Finally, CounterBean would contain one method to increment the counter variable, and another to get the counter variable for display.
Not necessary, I can simply override Link#onClick(). It would be trivial to write a Link component that uses it's id as a the name of a method that should be called on a model object, but I never needed to.
(The way I typically write JSF code, there would also be an index.jsp that just contains a single <jsp:forward> action. That's not necessary, but if it weren't there, you'd need to modify web.xml to change the welcome file list so that it loads "counter.jsf" by default.)
In your Application class constructor:
setHomePage(MyHomePage.class);
But that was a very simple example. The fun starts when you want to create your own components to avoid copy-and-paste code.
It is quite some time ago that I worked with JSF, but I think these steps are necessary to create a new component (please correct me if I'm wrong):
- implement StateHolder
- define a renderer (no standard template system available)
- create component type identifier
- register the component in faces-config.xml using the class name and component type identifier
- create a custom tag library XML descriptor with all attributes, again repeating the class name and introducing yet another identifier
- add taglib in JSP header before using it
This list is missing event handling and composite components.
In contrast to this, let's have a look at what I have to do to combine the two components of my example into one reusable component:
- Create a new class and copy the code from CounterPage.
That's how it looks:
class CounterComponent extends WebMarkupContainer {
public int counter = 0;
public CounterComponent(String id) {
super(id);
add(new Link("increase") {
public void onClick() {
counter = counter + 1;
}
});
add(new Label("counter", new PropertyModel(this, "counter")));
}
}
That's how it will be used:
add(new CounterComponent("mycounter"));
I know that JSF has it's advantages, but it would be nice if it didn't make trivial stuff so very complicated.
Timo
.
- References:
- Recommendations for a web application framework?
- From: Alan Meyer
- Re: Recommendations for a web application framework?
- From: David Segall
- Re: Recommendations for a web application framework?
- From: Alan Meyer
- Re: Recommendations for a web application framework?
- From: Chris Smith
- Re: Recommendations for a web application framework?
- From: Timo Stamm
- Re: Recommendations for a web application framework?
- From: Chris Smith
- Re: Recommendations for a web application framework?
- From: Timo Stamm
- Re: Recommendations for a web application framework?
- From: Chris Smith
- Recommendations for a web application framework?
- Prev by Date: Re: JFrame called Ghost doesn't show
- Next by Date: Re: Hello, will you allow a bit off-topic posting? Seek programmers interested in C-art
- Previous by thread: Re: Recommendations for a web application framework?
- Next by thread: Re: Recommendations for a web application framework?
- Index(es):
Relevant Pages
|