Overview : WEB4J Java Web Application Framework
The primary design goal of WEB4J is to always exercise deep compassion for you, the application programmer, to make your tasks as simple, natural, and as effective as possible. The framework should take on as much pain as possible, so that, in the end, you experience as little pain as possible.
The important things about WEB4J are :
- it's a full-stack Java web application framework
- it's small, and has a philosophy of deep simplicity and minimalism
- it can boost your productivity by 300% - 400% over other tools
- it's not free, it's not open source, and it has nothing to do with Rich Internet Apps
- it allows package-by-feature, where closely related items are placed in the same directory
- it lets you put SQL in plain .sql text files
- it lets you implement forms with plain HTML
- it has no reliance on javascript
- it has no custom annotations
- it has no custom .xml files (only web.xml is used)
- it has no tedious object-relational mapping
- it can be used with any relational database that has a JDBC driver
- it lets your Model Objects be immutable
- it lets your Model Objects be responsible for their own validation (as they should be)
- it lets your Model Objects avoid the Java Beans anti-pattern
- it uses a minimal toolset
- it doesn't take you long to learn (and you don't need to buy a book)
- it uses convention over configuration in several important ways
- it makes your application classes simple, and easy to maintain
- it requires minimal configuration
- it doesn't impose thread-safety constraints on your classes
- it lets multilingual apps have almost the same style as a single language app
- it lets your apps assist in their own translation
- it lets you place translations in the database
- it lets you avoid ResourceBundle and its defects
- it protects you from common hacks
- it's cheaper to use than open source tools
- it starts up quickly
In the interest of not wasting your time, please see below for a listing of its drawbacks.
If you can accept the above, then WEB4J is often the best tool for the job of creating browser interfaces to databases. Because of its deep simplicity, it allows markedly faster delivery of applications.
WEB4J is Small
One measure of complexity is size. Here is a listing of the number of documented classes in various tools :
| Name | Num Classes | Relative Size |
|---|---|---|
| WEB4J | 82 | |
| Servlet/JSP API | 96 | |
| Rails | 170 | |
| Struts | 720 | |
| Rife | 1,110 | |
| Tapestry | 1,140 | |
| JEE | 1,188 | |
| Spring | 2,464 |
As you can see, most tools have a size that might be described as "rather large". Note that WEB4J has the smallest surface area of any tool in its class. It is even less than half the size of Ruby on Rails, which has gained attention lately for its ease of use. Correspondingly, it takes a shorter time to learn WEB4J, and to implement features with it.
Not only is WEB4J compact, but, more importantly, applications built with WEB4J are compact as well. Here are some typical line counts per feature, taken from a cross section of several features in the Fish & Chips Club example application. (Documentation comments are included in the line counts.)
| Item | Avg Lines | Relative Size |
|---|---|---|
| SQL file (.sql) | 25 | |
| Presentation (.jsp) | 108 | |
| Total | 133 | |
| Model (.java) | 111 | |
| Action (.java) | 144 | |
| DAO (.java) | 46 | |
| Total | 301 |
In general, your code will only be roughly twice the size of the non-code elements of your application.
(DAOs are often short and simple, consisting only of a few single-line methods. In such cases, it is recommended that those methods be moved into the Action class.)
WEB4J Requires A Minimal Toolset
You use the following tools when building a WEB4J application :- views use HTML/CSS, JSP 2.0+/JSTL 1.1+, plus some custom WEB4J tags. The custom tags are minimal, and do not interfere with regular HTML. In particular, forms use plain HTML. (Note that WEB4J does not require javascript.)
- data access objects (DAOs) reference standard SQL statements placed in .sql text files. There is no database mapping of any kind.
- in general, your code uses web4j.jar, and the following commonly used tools : JDK 1.5+ and Servlets 2.4+. (EJBs are not used.)
WEB4J Uses Convention Over Configuration
Convention over configuration is used to reduce the effort needed to create and maintain your application. It is used in the following ways :- a default naming convention maps request URIs to corresponding Actions. See RequestParserImpl.
- in JSPs, a naming convention for the names of input controls allows for automatic mapping between controls and corresponding getXXX methods of a Model Object. This convention allows painless population of forms with data. See RequestParameter.
- an ordering convention for the columns of a ResultSet is used to map columns to corresponding parameters in a Model Object constructor. See the overview of the database package.
- an ordering convention is used for SQL statements with '?' parameters : when your DAO passes values for such parameters to the framework, the order of the passed parameters matches the order of the '?' items appearing in the underlying SQL statement. See Db.
- where possible, default implementations of required interfaces can be used with no effort on the part of the application programmer. If there is no default implementation, or if the default implementation is overridden, then a naming convention for the package/class can be used. See BuildImpl.
- the set of acceptable RequestParameters for each Action are found automatically by the framework upon startup, with no configuration required. See ApplicationFirewallImpl.
WEB4J Application Classes Are Usually Simple
The quality of a framework can be measured by examining the concrete classes which use it. Questions to ask of a such a class include :
- is it fairly simple and compact?
- does it read at a high level of abstraction?
- does it read clearly?
Model Objects :
Data Access Objects (DAOs) :Actions :
WEB4J Enables Package-By-Feature
The package-by-feature technique is a powerful method for organizing your code. It has many advantages, and is superior to the package-by-layer style so often promoted by other tools.All items related to a single feature can be isolated in their own directory/package - Action, Model Object, DAO, plain text SQL statements, and even the JSP. This gathering together of all items related to a single feature (and only that feature) is extremely satisfying. It allows the following goodness:
- say goodbye to tedious navigation from directory to directory to change closely related items - everything is in one place
- it allows deletion of unwanted features simply by deleting a single directory
- it allows some items to reduce scope from public to package-private. (Minimizing scope is a central idea of lasting value in programming, and should always be aggressively pursued.)
- in many source-code control environments, it allows developers to see immediately if another developer has checked out an item related to their current work
WEB4J Forms Use Plain HTML
Forms are an important part of web applications. Most frameworks implement forms with a large set of custom tags, that are different for each framework. These are meant to replace the existing, well known HTML controls such as <INPUT>, <SELECT>, and so on. That style is not the best, since it forces you to learn a new set of tools to do something you already know how to do - build an HTML form. This is neither necessary nor desirable.In WEBJ, the typical form looks like this :
<w:populate using="member"> <form action='MemberEdit.do' method="post"> <input name="Id" type="hidden"> <table align="center"> <tr> <td><label>Name</label> *</td> <td><input name="Name" type="text"></td> </tr> <tr> <td><label>Is Active?</label></td> <td><input name="Is Active" type="checkbox" value="true"></td> </tr> </w:populate> <tr> <td align="center" colspan=2> <input type="submit" value="Add/Edit"> </td> </tr> </table>The population of the form is done by wrapping a normal HTML form with a single <w:populate> tag - that's it. There are no custom tags for the various kinds of form controls. The WEB4J mechanism is the simplest possible way of populating forms.
WEB4J Has No Custom XML Files
The only XML file required by WEB4J is the deployment descriptor, web.xml. Whereas many other tools force you to spend significant time coding in XML, WEB4J was explicitly designed to let you avoid it.In a WEB4J app, you implement features using JSPs, Java, and text files containing SQL statements. That's it. If you are looking for "XML hell", you won't find it here (but you can certainly find it in many other tools).
WEB4J Doesn't Use Object Relational Mapping
When building DAOs, you may use either WEB4J's data layer or any other tool. By design, WEB4J's data layer doesn't use object-relational mapping (ORM). For the majority of cases, implementing a DAO method with WEB4J's data layer will be more compact than an ORM implementation. The minority case in which an ORM tool may result in less coding effort and increased elegance is that of building an extensive object graph.However, building an extensive object graph is the exception, not the rule. The majority of pages in a typical application relate not to relatively complex views of data, but to relatively simple ones. The reason for this is that it matches how people think, and how they work - on one specific thing at a time. Yes, large summary pages are very often part of an application, but such pages are usually the exception, not the rule.
There are some serious drawbacks to object-relational mapping :
- it replaces standard SQL with alternate query mechanisms (reinventing the wheel).
- it makes it difficult to debug and tune SQL, since the SQL is generated behind the scenes.
- it often forces you to code in XML, which is inherently more difficult to work with.
- its details are often non-trivial to learn and use.
- it's often tedious and verbose.
- it destroys the clear separation between application layer and data layer.
- it violates encapsulation of database secrets, since the application layer repeats information that's usually hidden in the database: column types, nullity, key information, and so on. (SQL statements never explicitly include such information.)
- perhaps requiring you to add a no-argument constructor
- perhaps requiring your class to be non-final
- perhaps requiring you to add setXXX methods (roughly doubling the number of methods)
- perhaps requiring you to add annotations
- perhaps requiring you to implement Serializable (doing this correctly is non-trivial)
In WEB4J, these restrictions don't exist. The only restriction for WEB4J Model Objects is that the constructor must throw a ModelCtorException, and that restriction has nothing to do with persistence. Rather, it's related to an important problem each Model Object should solve: the problem of validating state, and communicating related errors to the caller.
WEB4J Uses Plain .sql Text Files
The WEB4J data layer uses regular SQL statements, stored in ordinary .sql text files. Here is an example showing the basic idea. This style has many benefits.WEB4J Has Minimal Configuration
WEB4J has no .xml configuration files, other than the familiar web.xml file (used for a number of initialization settings). In addition, it requires the application programmer to supply concrete implementations for a number of interfaces. Default implementations are supplied for about half of these items (no reasonable defaults are possible for the others). See BuildImpl for details.WEB4J Does Not Impose Thread-Safety Constraints
Some tools force some application classes to be thread-safe. In Struts 1, for example, Action classes must be thread-safe. Forcing such a requirement on an application programmer is inappropriate :- implementing thread-safety is not trivial, especially for novice programmers
- even if the programmer is experienced with the issue of thread-safety, it is still dangerously easy to simply forget to enforce it. Thus, there is the continual danger of introducing thread-related bugs.
WEB4J Allows Multilingual Apps To Feel Like Single Language Apps
WEB4J translation tools allow the implementation of a multilingual application to look almost the same as that of an ordinary single language application. All Actions, Model Objects, and DAOs are exactly the same in both cases.The only differences are in JSPs - and even there, the differences are relatively minor. The markup retains the overall look of a single language application. It remains legible, and appears natural to the eye. This is because the WEB4J translation tags are designed explicitly to be non-invasive. For example,
- translation of large chunks of markup can be often be implemented by wrapping the 'single language' markup in a TextFlow tag
- translation of all tool tips (TITLE attributes) can be done by placing a single Tooltips tag in a template JSP
WEB4J Allows Applications To Assist In Their Own Translation
The WEB4J translation mechanism can be backed by a database (recommended), or by any other means, including properties files. If a database is used to store translations, then applications can assist in their own translation.The general idea is that, during development, all user interface items needing translation can be collected simply by exercising the application. This is done with a Translator implementation that records items having missing translations. Translations for such items can then be added later, through the browser, using screens created for that purpose, just like any other data. (Please see the WEB4J example application for further illustration of this useful technique.)
WEB4J Protects You From Common Hacks
WEB4J has tools to protect you from common hacks :- SQL Injection attacks are not possible when using the WEB4J data layer, since it always uses a PreparedStatement in the background.
- SafeText models free-form user input, and automatically escapes special HTML characters (by default). This protects you against XSS attacks. It also allows you to forget about repeatedly escaping special characters in the view.
- CsrfFilter protects you against CSRF attacks.
- ApplicationFirewallImpl checks that all incoming parameters have known names, and that their values satisfy basic sanity checks.
- SpamDetector helps you prevent spam from entering your database.
WEB4J Is Cheaper Than Open Source Tools
WEB4J is cheaper to use than open source tools because it is so much easier to learn and use.There are three costs associated with any tool, not one :
- the cost of acquiring it
- the cost of learning it
- the cost of using it
In almost all instances, the acquisition cost is only a small fraction of a project's total budget.
Example : Spring + Hibernate versus WEB4J
Here is a nominal example having books costing $40, and developer time costing $1,000/week. (These figures are taken as a simple representative example. Regardless of what numbers seem reasonable to you, the basic result is the same.)
| Cost | Spring + Hibernate | WEB4J |
|---|---|---|
| Acquire | $0 | $20 |
| Learn | $4,080 [2 books + 4 weeks] | $1,000 [1 week] |
| Use | $500/feature [2.5 days/feature] | $140/feature [0.7 days/feature] |
| Total Cost Of 10 Features | $9,080 | $2,420 |
The reduction in both 'learning' and 'using' costs are of course related : things that are easier to learn are easier to use.
All tools have a cost. Free open source tools are "free" only if you don't need to buy a book, and only if your time has no cost to you.
WEB4J Has An Example Application
WEB4J comes with an extensive example application. Its modules are typical for a business application :- a main business domain
- access control - adding users, changing roles, resetting passwords
- user preferences - changing language, changing passwords
- webmaster tools - diagnostics, logging config, performance stats
- translation - adding and editing translations of text appearing in the user interface
The WEB4J example application is provided as both a starting point and as a guide. It is recommended, though not required, that your applications be created by starting with the example, and changing it gradually. If any items are undesired, then they are simply removed by deleting directories (and any links from menus). This is only possible because of the package-by-feature style recommended by WEB4J. (See the User Guide for more information.)
This approach is consistent with the following :
- destroying things is easiest of all
- next, changing something that already exists is usually easier than starting with nothing
- finally, starting with nothing usually takes the most time
In any case, the classes in the example application are always effective guides.
Other WEB4J Features
- action classes are usually automatically mapped to URIs, without any manual configuration (see RequestParserImpl)
- several abstract base classes are provided as templates for common action classes (see the subclasses of ActionImpl)
- Report helps you build reports quickly
- ModelUtil helps you implement equals, hashCode, and toString in your Model Objects
- Check and Validator implement many common validations, and can be extended with validations particular to your application
- ModelFromRequest and Db allow rapid creation of Model Objects from incoming requests and ResultSets, respectively.
- messages to the user can survive a redirect, allowing the application to inform the user of successful edits to the database
- settings in web.xml are used to establish application-wide default formats for dates and currencies
- the Db class is the main tool for implementing DAO methods
- applications can easily use multiple databases, when required
- upon startup, WEB4J can optionally perform a test precompilation of all SQL statements. This is highly beneficial since it detects errors at startup-time instead of at run-time. (Not supported by all database drivers.)
- if the database is down when the container starts, your app will attempt to recover with each incoming request. As soon as the database is up, your web app will start functioning normally.
- the webmaster is emailed if an error occurs, or if your application's response time exceeds a configured number of seconds. In the case of an error, the email includes extensive diagnostic information, including a stack trace
- upon startup, WEB4J will scan your Model Objects for possible Cross-Site Scripting vulnerabilities
- and other features as well...
WEB4J Has Drawbacks
All tools have drawbacks and trade-offs.How many times have you become disillusioned with a tool, but only after you have invested a lot of time and effort in it? The purpose of this section is to make sure that doesn't happen to you with WEB4J, by listing items you should know about.
Tools which don't clearly state their own drawbacks don't have your best interests in mind.
WEB4J's philosophy is one of deep minimalism. Thus, WEB4J may not include things which you might feel should be there:
- it has no library of fancy user interface widgets. It's likely not appropriate to use WEB4J for building Rich Internet Apps - although you may still like its data layer.
- it has no items related to Ajax, Web Services, or Messaging.
- it doesn't generate JavaScript.
- it doesn't have a CAPTCHA mechanism.
- it has no components, events, listeners, and so on (as in desktop programming).
- it uses JSP/JSTL, and alternative tools such as Velocity aren't supported.
- its form population mechanism doesn't include a way of changing the appearance of controls containing erroneous user input, nor for associating specific error messages with specific controls.
- for spreadsheet-style forms, no parsing of request parameter names to extract numeric row identifiers is performed.
- its data layer builds simple Model Objects in a single step. It can also build the simplest kinds of Parent-Child relations. But if you need to build a complex Model Object, containing many collections, then you will usually need to build such objects in several steps.
- when displaying an existing Model Object (built from an SQL statement) in a form, the data is formatted by the <w:populate> tag using application-wide format settings defined in web.xml, with no override. Some may find this pleasing, while others may find it an onerous constraint.
You May Need Third Party Tools
WEB4J doesn't depend on any third party tools or jars other than those published by Sun and expected in a servlet environment (Servlet API, JSP/JSTL). Thus, adding third party tools to your WEB4J application may well be necessary. Examples of tools you might have to add:
| Task | Example Tool |
|---|---|
| Unit Testing | JUnit |
| Feature Testing | HttpUnit |
| Build Scripts | Apache Ant |
| File Upload | Commons FileUpload |
| Charting | JFreeChart, Google Charts |
| PDF Generation | iText |
| Microsoft File Formats | Apache POI |
| Dependency Injection | Google Guice |
| Aspect Programming | AspectJ |
The toString, equals, and hashCode Methods Have Some Repetition
WEB4J provides good tools for implementing toString, equals, and hashCode. For each Model Object, the implementations of these methods vary in details, but their general technique or style is always the same. It would be very satisfying if these "general techniques" could be defined in one place.
There doesn't seem to be a satisfactory way of doing this with standard techniques of object programming. You may want to try and remove that repetition by using aspect programming tools such as AspectJ. Using JDK 5 annotations may be another option.
Backwards Compatibility Issues
We apologize for making occasional changes that are not backwards compatible. Such changes occur only when deemed necessary for the long term quality of the tool, in the direction of increasing elegance and simplicity. Such changes are never large scale, but it doesn't take much to break backwards compatibility. If you need to update an existing WEB4J app to a new version of web4j.jar, you may need to perform some 'migrations' to the new way of doing things, using the Version History to find items that may affect you.
You should evaluate the recent Version History to see if you are comfortable with the size and frequency of such changes.
It's true that there isn't much positive to say about such changes, except for this: it allows the tool to remain aggressively minimalistic, and increases its overall elegance.