jWebApp is among the easiest web frameworks to learn and use, and allows for extremely fast web application development. By default, jWebApp uses a simple URI to object mapping controller, providing a totally configuration and annotation free mode. jWebApp also supports a simple XML based configuration that allows for object reuse, regular expression matching of URIs, configuration based forwarding, redirects, validation, role based security, SSL, error handling and a lot more. You can simply use JSP/JSTL, Velocity, etc., along with plain HTML and HTML forms.
If we were to ask ourselves “what are we actually doing with a web application”, the answer would be something like “we are associating application code with a web request”. Putting it another way we are associating application code with a URL and an HTTP method (GET or POST). So, in the end, all our web framework really needs to do is reliably map a URL:
http://host/[context/]customerHandler/viewCustomer?customerId=value
to an object and method:
public class CustomerHandler extends RequestHandler
{
public String processViewCustomer(ServerInterface serverInterface)
{
String customerId = serverInterface.getParameter(“customerId”);
serverInterface.setAttribute("customer", jpersist.loadObject(new Customer(customerId));
return "/WEB-INF/customer.jsp";
}
}
jWebApp provides the shortest path from your web URL to application code without any need for configuration or annotation. As an example, if you have a customer oriented web site and have a means for registering new customers, you might have a request handler that handles saving and viewing the customer’s information:
public class CustomerHandler extends RequestHandler
{
// processRequest is the default when no method is included
public String processRequest(ServerInterface serverInterface) {...}
public String processViewCustomer(ServerInterface serverInterface) {...}
public String validateSaveCustomer(ServerInterface serverInterface) {...}
public String processSaveCustomer(ServerInterface serverInterface) {...}
}
With jWebApp, to access the methods you would use the following URLs:
// the default
http://host/[context/]customerHandler
http://host/[context/]customerHandler/saveCustomer
http://host/[context/]customerHandler/viewCustomer?customerId=value
The URL contains the class name optionally followed by the method name:
http://host/[context/]className[/methodName]
or, for our purposes:
http://host/[context/]customerHandler[/saveCustomer]
and, it actually is just that simple! jWebApp goes to great lengths to handle finding the application code needed to satisfy the request. You can define all or part of the classpath for the class in the URL, and there can be any number of methods defined in the class for any number of mappings. Mappings must be preceded with “validate” or “process”, so no methods can be called that aren’t callable. Classes can also be defined as part of a package (defined in the web.xml file) so that only classes in the package can be called, and jWebApp also allows that amount of the classpath to be omitted from the URL. Once the class and method is found, it is executed and cached for future calls. URL’s can also contain extra path information either before the class/method or after. jWebApp also supports all forms of servlet mapping (path, extension, exact, etc).
What is done in the mapped method is entirely up to the developer. In most cases we are either saving user entered data or loading data to be presented to a user. jWebApp provides a ton of functionality to make the developers life easier, and because jWebApp isn’t all controlling, the developer is free to use any other tools (APIs, taglibs, etc).
You may also have noticed that jWebApp is naturally RESTful. With jWebApp, you can use the same configuration and annotation free URI mapping controller to handle REST based web services using any of the HTTP verbs that are used with REST (GET, HEAD, PUT, POST, DELETE, OPTIONS). jWebApp also supports a more formal REST mode by extending RestfulHandler and implementing the HTTP verbs. Either way, you are RESTful.
In order to provide a more detailed example, we will also be using jPersist (included with jWebApp).
We’ll define a class to handle our customer’s information:
public class Customer
{
String customerId, firstName, lastName, address1, address2, city, state, country, phone, email;
public String getCustomerId() { return customerId; }
public void setCustomerId(String _customerId) { customerId = _customerId; }
...
}
it is a simple POJO with attributes and getters/setters. jPersist is POJO oriented as well as persistence oriented (by simply extending PersistentObject). To setup a jPersist database manager, simply use one of the DatabaseManager’s factory methods. jWebApp provides servlet initialization and destruction methods which are defined with the servlet in the web.xml file.
Our application setup is simple:
public class AppUtils extends InitDestroyHandler
{
private static DatabaseManager dbManager;
public void init(ServletContext context)
{
dbManager = DatabaseManager.getJndiDefinedDatabaseManager("contacts", 15,
"jdbc/contacts", null, null);
}
public static DatabaseManager getDatabaseManager() { return dbManager; }
}
The above is all that is needed by either jWebApp or jPersist (you have to define your JNDI resource, but that’s a servlet thing).
Now our URLs (HTTP requests) as defined above:
http://host/[context/]customerHandler
http://host/[context/]customerHandler/saveCustomer
http://host/[context/]customerHandler/viewCustomer?customerId=value
map to the following class and methods:
public class CustomerHandler extends RequestHandler
{
// AppUtils is initialized before any requests are handled.
DatabaseManager dbm = AppUtils.getDatabaseManager();
// We can have a default request: http://host/[context/]customerHandler
public String processRequest(ServerInterface serverInterface)
{
return "/WEB-INF/customer.jsp"; // send the user to a page/form
}
// Load customer information based on customerId
public String processViewCustomer(ServerInterface serverInterface)
{
String customerId = serverInterface.getParameter(“customerId”);
// jPersist builds a JDBC query based on your object and its data
serverInterface.setAttribute("customer", dbm.loadObject(new Customer(customerId));
return "/WEB-INF/customer.jsp";
}
// Any method can have a validation method associated with it.
public String validateSaveCustomer(ServerInterface serverInterface)
{
// If validation fails send an error message and return to a web page.
// Otherwise:
return SUCCESS;
}
// If the validation method returns SUCCESS, then the process method is called.
public String processSaveCustomer(ServerInterface serverInterface)
{
Customer customer = new Customer();
// automatically fill an object with the request data matches property values.
serverInterface.fillObjectFromRequest(customer);
dbm.saveObject(customer);
return "/WEB-INF/orders.jsp";
}
}
Your request mapped methods can forward anywhere any number of times, but at some point they need to return an address to a page renderer such as JSP (*.jsp) or Velocity (*.vm), or return NO_FORWARDING if there is no response to be sent.
Of course, with any framework there’s always a lot more to it then is presented in a short article, and this is true with jWebApp as well. But, what you see here is pretty well all you need to know to develop complex database driven web applications.
With jWebApp there’s no configuration required, no XML, no annotations, and no additional (proprietary) tag libraries. You can always use simple HTML and HTML forms and anything else you like. And for presentation you can use JSP/JSTL, Velocity, or anything you like here as well.
In short, with jWebApp, what you already know is actually all you need to know.
Blogging About
jPersist, jWebApp, Persistence, Web Frameworks, Databases, Open Source, Consulting
Most Popular Blog Entries
Project Websites
This Site Powered by
&