jWebApp is a Java servlet-based model-view-controller web application framework that is specifically designed to satisfy the need for extremely simple web development. In fact, jWebApp is so simple, it can actually be learned in a matter of minutes.
jWebApp is as easy as:
public class HelloWorld extends RequestHandler
{
public String hello()
{
getServerInterface().addViewObject("helloWorld", "Hello World");
return "/WEB-INF/helloWorld.jsp";
}
}
Just plain HTML and your favorite template markup:
<div align="center">
<h3>Hello, This Is A Simple "Hello World" Example.</h3>
<h2>${helloWorld}</h2>
</div>
Calling the above is simple:
http://host/context/helloWorld/hello
The following servlet configuration is all that is needed (outside our control, it's a servlet thing):
<servlet>
<servlet-name>jwaRequestServlet</servlet-name>
<servlet-class>jwebapp.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/helloWorld/hello</url-pattern>
</servlet-mapping>
That's it! No other XML, annotation, or configuration is needed!
jWebApp provides support for all of the features you expect, but does not need additional tag libraries or extensive APIs to implement them, what you already know is all you will need. With jWebApp, you can use any model/business layer technologies, any database-access technologies, any web-authoring technologies, and plain old HTML and HTML forms.
With jWebApp you have a configuration free mode where you simply drive the web application with URIs. jWebApp automatically finds the class instance required to satisfy a request.
For example, with the following URL:
http://www.website.com/application/HelloWorld
jWebApp would, by default, find a class named [webapp.][application.]HelloWorld.class.
jWebApp will automatically load the class and, by default, call the method “validateRequest” if it exists. jWebApp then calls the method “request” which must exist (or an HTTP not found error is returned).
The URI can be anything as long as all or part of it identifies a locatable class. All of jWebApp’s functionality is available in code and the methods only need to return a forwarding URI, which can be another request handler or a final destination such as a JSP or Velocity page. The methods can also return NO_FORWARDING if there is no need for forwarding (no data is returned to the client).
jWebApp also provides for mapping web requests to methods within a class.
As another example, with the following URL:
http://www.website.com/application/manageUsers/newUser
jWebApp would, by default, find a class named [webapp.][application.]ManageUsers.class. jWebApp loads an instance of the class and optionally calls the method “validateNewUser” if it exists. jWebApp then calls the method “newUser” which must exist (or an HTTP not found error is returned).
jWebApp provides another configuration free mode that provides server side support for REST (RESTful web services). REST is based on HTTP concepts, and is simply the use of the 6 most common HTTP request methods (POST, GET, PUT, DELETE, HEAD and OPTIONS). Which, as defined in both HTTP and REST, correspond to CRUD type operations:
POST (create - also insert, update, delete, append)
GET (read - also select, get)
PUT (update - also insert, update, replace)
DELETE (delete - also remove, cut)
HEAD (same as get without data/body - just headers)
OPTIONS (what HTTP methods are supported)
Regular jWebApp request handling is also RESTful (for GET and POST only) as long as the GET request handles read only operations with no side effects (no updates, deletes, state changes, etc.) Requests are also RESTful if they have query strings. By definition, REST does not allow for session tracking or cookies (they are still available with jWebApp), and authentication (also available with jWebApp) is handled as defined for HTTP (via request headers).
jWebApp also provides a completely optional, but simple, XML configuration mode which consists of:
<jwebapp>
<request id="" match="" matchRegExp="" secureConnection=""
handlerClass="" handlerMethod=””>
<security role="" />
<parameter name="" value="" />
<forward id="" key="" protocol="" url="" rewrite=""/>
<redirect id="" key="" protocol="" url="" rewrite=""/>
<validation id="" parameterName="" type="" arguments="" errorMessage=""/>
</request>
<jwaUrl id="" protocol="" url="" rewrite=""/>
<message id="" value="" />
</jwebapp>
This mode provides the ability for class and method reuse, passing in static parameters, regular expression matching of URIs, soft coded URIs, and soft coded messages. jWebApp configuration even allows overriding configuration free and other configurations. The configuration mode also provides for XML defined security, forwarding, redirects and validation.
See the configuration manual for more details.
In both configuration free and configuration based cases, the request handler is a class that extends RequestHandler (RestfulHandler for REST), for example:
public class MyRequestHandler extends RequestHandler
{
// optional validator
public String validateRequest(ServerInterface serverInt) { … }
// default handler
public String processRequest(ServerInterface serverInt) { … }
// optional validator
public String validateNewUser(ServerInterface serverInt) { … }
public String processNewUser(ServerInterface serverInt) { … }
}
For RESTful web services:
public class MyRestfulHandler extends RestfulHandler
{
// Handles HTTP GET request.
public String get(ServerInterface serverInterface, String[] args) { ... }
// Handles HTTP HEAD request.
public String head(ServerInterface serverInterface, String[] args) { ... }
// Handles HTTP PUT request.
public String put(ServerInterface serverInterface, String[] args) { ... }
// Handles HTTP POST request.
public String post(ServerInterface serverInterface, String[] args) { ... }
// Handles HTTP DELETE request.
public String delete(ServerInterface serverInterface, String[] args) { ... }
// Handles HTTP OPTIONS request.
public String options(ServerInterface serverInterface, String[] args) { ... }
}
All parameters are optional and you can also use HttpServletRequest and/or HttpServletResponse as parameters.
In a configuration free mode, the only need is for the class to be in the package “webapp” (default), which is optionally definable in the web.xml file via the init parameter “classPrefix”:
<init-param>
<param-name>classPrefix</param-name>
<param-value>webapp</param-value>
</init-param>
And of course, the class/JAR files need to be locatable (usually in the WEB-INF/classes and/or WEB-INF/lib directory).
That’s it, that’s all there is to jWebApps configuration free automatic URI mapping!
Installing a jWebApp project is simply a matter of copying the “jwebapp_XX.war“ file of choice to your web server’s auto-deploy directory “webapps”. Your web server will automatically unpack and install the web application. You can also simply unzip the archive (WARs are zip files). It’s also possible to rename the “.war” file to “.zip” and unzip the archive.
Once installed simply start development of your webapp.
If you need a web server, simply download and install Apache’s Tomcat, Coucho’s Resin or Jetty. They are free and easy to install and run. There are many J2EE web servers that you can also use.
Resin is extremely easy on Windows’ platforms. Simply unzip Resin in the directory of your choice and run ‘httpd.exe’. Copy the ‘jwebapp_XX.war’ file to the webapps directory and you’re done.
jWebApp is easy to set up and use with your projects, and follows the typical setup for Java web technology applications:
/
/images/
/WEB-INF/
/WEB-INF/classes/
/WEB-INF/content/
/WEB-INF/include/
/WEB-INF/lib/
/WEB-INF/web.xml
/WEB-INF/webapp.xml
/WEB-INF/mainpage.jsp
index.jsp
where ‘/’ is any directory you like. This is our typical setup, but you are free to use any workable setup you like. In a configuration free mode the webapp.xml file is not needed. But even in a configuration free mode it’s still quite useful for defining non-hardcoded URIs and messages.
The JAR files in the “WEB-INF/lib” directory can also be located in your web server’s “common” or “shared” lib directory (container dependent), where they will be available to all applications. However, if you’re working with multiple versions of a jar, it may be better to keep them in the project’s lib directory to keep them isolated from other applications.
Working with jWebApp is no different than working with any other Java web technology, only much simpler.
Page authoring can be handled with any view technology you like. JSP/JSTL is a good choice, and so is Apache’s Velocity.
All attributes set with getServerInterface().addViewObject() and getServerInterface().setAttribute(), which simply calls the servlet request’s setAttribute(), are available to the page author via JSP or Velocity expressions:
${attributeName}
Servlets provide several implicit objects (such as ${param}) that are always available to the page author. jWebApp also provides several implicit objects, summarized by the following table:
|
${jwaUrl.id} |
provides URLs as defined in the jwaUrl, forward, and redirect definitions in your configuration file |
|
${jwaMessage.id} |
Access messages defined in the XML configuration file |
|
${requestContextPath} |
The servlet context |
|
${requestServletPath} |
The servlet path (exact or path oriented paths only) |
|
${requestPathInfo} |
The request extra path information (follows servlet path) |
|
${requestQueryString} |
The request query string |
|
${ requestUri} |
The request URI |
|
${ requestUrl} |
The request URL |
|
${ requestScheme} |
The request scheme (http, https, etc.) |
|
${ requestServerName} |
The server name the request called |
|
${ requestServerPort} |
The port the request called |
|
${ requestLocalName} |
The local server name |
|
${ requestLocalPort} |
The local port name |
|
${jwaRemoteUser} |
Contains the remote user id |
|
${jwaRemoteUserInformation} |
provides the following properties for accessing user information:
${jwaRemoteUserInformation.userId}, ${jwaRemoteUserInformation.salutation}, ${jwaRemoteUserInformation.firstName}, ${jwaRemoteUserInformation.lastName}, ${jwaRemoteUserInformation.roleMap}
|
Download jPersist and jWebApp for Java 1.5-1.6
Download jPersist and jWebApp for Java 1.2-1.4
Download All Examples for Java 1.5-1.6
Download All Examples for Java 1.2-1.4
All our projects are open source and located on SourceForge.net. All support requests, bug reports, code access, etc. can be found at SourceForge.net
If you would like to contribute code and/or fixes, please send a support request (via SourceForge.net) requesting commit access to our repository.
jPersist & jWebApp will be complete with the release of jPersist2 (except for minor releases). The idea behind these projects is to have as simple an object/relational persistence API, and web development framework as is possible. So we don't want to develop these projects further with the exception of integrations and plug-ins/add-ons.
jPersist & jWebApp can be found at https://sourceforge.net/projects/jpersistjwebapp
Email: cinfo@jwebapp.com
public class HelloWorld extends RequestHandler
{
public String hello()
{
getServerInterface().addViewObject("helloWorld", "Hello World");
return "/WEB-INF/helloWorld.jsp";
}
}
<div align="center">
<h3>Hello, This Is A Simple "Hello World" Example.</h3>
<h2>${helloWorld}</h2>
</div>
http://host/context/helloWorld/hello
<servlet>
<servlet-name>jwaRequestServlet</servlet-name>
<servlet-class>jwebapp.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/helloWorld/hello</url-pattern>
</servlet-mapping>
The following demonstrates the optional form features of jWebApp. jWebApp handles forms easily and without a bunch of tags. With jWebApp Interfacing between JSP and HTML forms is trivial.
Simply register an object for automatic form/object mapping:
serverInterface.addFormObject("objectName", object);
When a form is submitted, jWebApp automatically fills the object with data by matching form fields to object properties via property naming (ex. customerName). The object can be retrieved at anytime with getServerInterface().getFormObject():
Customer customer = getServerInterface().getFormObject("customer");
Simply use plain HTML and and your favorite template markup with ${form.anyObjectProperty}, and jWebapp will automatically handle populating the form/object:
<p>Customer Name
<input type="text" name="customerName" value="${form.customerName}" /></p>
With all the third party tag libraries (only JSTL is really needed), and with all the Javascript frameworks like jQuery and Dojo, there just is isn't a need for the tags that other frameworks force us to use. With jWebApp you simply use JSP/Velocity/etc, plain old HTML forms/tags, and your favorite javascript framework (or not).
The following is all that is needed to handle file uploads with jWebApp:
MultipartFormData mfd = getServerInterface().getMultipartFormData("filename");
mfd.getStoredLocation().renameTo(new File(newPath));
Simply Use typical HTML file upload form:
<input type="file" name="filename" />
This example sends an email with an image attachment that is also embedded in an HTML document
EmailSender es = new EmailSender("localhost");
es.setDebug(true);
es.addSendTo("user@somehost.net","User");
es.addReplyTo("david@localhost.com", "David");
es.setSentFrom("dlb@localhost.com", "David");
es.setSubject("This is an example");
String html = "<html><body><h1>This is an example message</h1>"
+ "<b>This is an example image <img src='cid:image'> message</b>"
+ "</body></html>";
es.addHtml(html);
es.addAttachment("image","images/logo_2_200x70.jpg","This is an example",false);
es.addHtml("<html><body><h1>This is an example message</h1></body></html>");
es.sendEmail();
The following is a jWebApp example of sending a backend payment to PayPal.
String username = "test_api1.host.com",
password = "VBAACCMQ5CN3V96D",
signature = "AXuvVdpyAeZUtSJ1yWJuCV6a8i33AdI-s9Lloti4HOkrytGZR7PeCH1q",
environment = "sandbox",
ipAddress = "1.1.1.1";
DirectPayment pp = new DirectPayment(username, password, signature, environment);
CreditCardInformation cci = new CreditCardInformation("0000000000000000",
"Visa", "000", "11", "2007");
CardOwnerInformation coi = new CardOwnerInformation("David", "B",
"123 No Street Drive", null, "Glendale", "AZ", "43844", "US");
pp.directPayment(ipAddress, 123.99, cci, coi);
The following demonstrates using the same URI mapping features of jWebApp to map URIs to scripts. Any BSF (Apache Bean Scripting Framework) supported scripting language can be used. And the scripts can be added dynamically anytime. With script caching turned off the scripts can even be modified at anytime.
print ("hello world"); // prints to the standard output log
serverInterface.addViewObject("helloWorldMessage",
"Hello, this is a scripting example");
return "/WEB-INF/helloWorld.jsp";
print ("hello again world"); // prints to the standard output log
serverInterface.addViewObject("helloWorldMessage",
"Hello again, this is another scripting example");
return "/WEB-INF/helloWorld.jsp";
<div align="center">
<h3>Hello, This Is A Simple "Hello World" Scripting Example.</h3>
<h2>${helloWorldMessage}</h2>
</div>
<!--
Can execute any script in the scriptingDirectory. The script
filename is obtained from the servlet's extra path information.
See HttpServletRequest.getPathInfo()
-->
<request id="scripts" handlerClass="jwebapp.request.Scripting">
<parameter name="scriptFileNameExtension" value="bsh" />
<parameter name="scriptingDirectory" value="/WEB-INF/scripts" />
<!-- You can also pass arguments to your scripts -->
<parameter name="myScriptArg" value="myScriptArgValue" />
</request>
<!-- Only allows the following script -->
<request id="script" handlerClass="jwebapp.request.Scripting">
<parameter name="scriptFileName" value="/WEB-INF/scripts/hello.bsh" />
</request>
http://host/context/script
http://host/context/scripts/hello
http://host/context/scripts/helloAgain
<servlet>
<servlet-name>jwaRequestServlet</servlet-name>
<servlet-class>jwebapp.RequestServlet</servlet-class>
<init-param>
<param-name>configFile</param-name>
<param-value>/WEB-INF/webapp.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/script</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/scripts/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
public class AjaxExample extends RequestHandler
{
public String jsonDate() throws IOException
{
getServerInterface().addViewObject("date", new DateInfo());
return "/WEB-INF/jsonDate.jsp";
}
public static class DateInfo
{
Calendar c = new GregorianCalendar();
DateFormatSymbols dfs = new DateFormatSymbols();
public String getDayOfWeek() { return dfs.getWeekdays()[c.get(Calendar.DAY_OF_WEEK)]; }
public String getDayOfMonth() { return fixLength("" + c.get(Calendar.DAY_OF_MONTH)); }
public String getMonth() { return dfs.getMonths()[c.get(Calendar.MONTH)]; }
public String getYear() { return "" + c.get(Calendar.YEAR); }
public String getHour() { return fixLength("" + c.get(Calendar.HOUR_OF_DAY)); }
public String getMinute() { return fixLength("" + c.get(Calendar.MINUTE)); }
public String getSecond() { return fixLength("" + c.get(Calendar.SECOND)); }
static String fixLength(String str) { return (str.length() == 1 ? "0" : "") + str; }
}
}
<%@ page contentType="text/plain" %>
/*
JSON formatted date - of course, you can also use any number of Ajax and
JSON libraries.
See: http://www.json.org and http://www.jquery.org
*/
{ "dayOfWeek" : "${date.dayOfWeek}",
"dayOfMonth" : "${date.dayOfMonth}",
"month" : "${date.month}",
"year" : "${date.year}",
"hour" : "${date.hour}",
"minute" : "${date.minute}",
"second" : "${date.second}",
"message" : "(Click for update)" }
http://host/context/ajaxExample
<html>
<head>
<title>
Simple Ajax Example
</title>
<script type="text/javascript" src="${jwaContextPath}/scripts/jquery.js"></script>
<script>
<!--
function serverTime(htmlElement)
{
$.get("${jwaContextPath}/ajaxExample/jsonDate.jwa",
function(data)
{
dateObj = eval("(" + data + ")");
htmlElement.innerHTML = dateObj.dayOfWeek + " "
+ dateObj.month + " "
+ dateObj.dayOfMonth + ", "
+ dateObj.year + " "
+ dateObj.hour + ":"
+ dateObj.minute + ":"
+ dateObj.second + " "
+ dateObj.message;
}
);
}
-->
</script>
</head>
<body>
<h2>Simple Ajax Example</h2>
<p onclick="serverTime(this);">Click Here for Server Time</p>
<p onclick="serverTime(this);">Click Here for Server Time</p>
</body>
</html>
<servlet>
<servlet-name>jwaRequestServlet</servlet-name>
<servlet-class>jwebapp.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/ajaxExample/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
public class RestfulSimpleStorage extends RestfulHandler
{
public String get() {...}
// or public String get(ServerInterface serverinterface, String[] args) {...}
// or public String get(String[] args) {...}
public String put() {...}
public String post() {...}
public String delete() {...}
public String head() {...}
public String options() {...}
}
<servlet-mapping>
<servlet-name>jwaRequestServlet</servlet-name>
<url-pattern>/restfulSimpleStorage/*</url-pattern>
</servlet-mapping>
http://host/context/restfulSimpleStorage/accountName[/containerName[/objectName]]