Chapter 13: Simple Web Applications
+++++++++++++++++++++++++++++++++++
One of the major benefits of using Jython is the ability to make
use of Java platform capabilities programming in the Python
programming language instead of Java. In the Java world today, the
most widely used web development technique is the Java servlet. Now
in JavaEE, there are techniques and frameworks used so that we can
essentially code HTML or other markup languages as opposed to
writing pure Java servlets. However, sometimes writing a pure Java
servlet still has its advantages. We can use Jython to write
servlets and this adds many more advantages above and beyond what
Java has to offer because now we can make use of Python language
features as well. Similarly, we can code web start applications
using Jython instead of pure Java to make our lives easier. Coding
these applications in pure Java has proven sometimes to be a
difficult and sometimes grueling task. We can use some of the
techniques available in Jython to make our lives easier. We can
even code WSGI applications with Jython making use of the *modjy*
integration in the Jython project.
In this chapter, we will cover three techniques for coding simple
web applications using Jython: servlets, web start, and WSGI. We’ll
get into details on using each of these different techniques here,
but we will discuss deployment of such solutions in Chapter 17.
Servlets
========
Servlets are a Java platform technology for building web-based
applications. They are a platform- and server-independent
technology for serving content to the web. If you are unfamiliar
with Java servlets, it would be worthwhile to learn more about
them. An excellent resource is wikipedia
(http://en.wikipedia.org/wiki/Java_Servlet); however, there are a
number of other great places to find out more about Java servlets.
Writing servlets in Jython is a very productive and easy way to
make use of Jython within a web application. Java servlets are
rarely written using straight Java anymore. Most Java developers
make use of Java Server Pages (JSP), Java Server Faces (JSF), or
some other framework so that they can use a markup language to work
with web content as opposed to only working with Java code.
However, in some cases it is still quite useful to use a pure Java
servlet. For these cases we can make our lives easier by using
Jython instead. There are also great use-cases for JSP; similarly,
we can use Jython for implementing the logic in our JSP code. The
latter technique allows us to apply a model-view-controller (MVC)
paradigm to our programming model, where we separate our front-end
markup from any implementation logic. Either technique is rather
easy to implement, and you can even add this functionality to any
existing Java web application without any trouble.
Another feature offered to us by Jython servlet usage is dynamic
testing. Because Jython compiles at runtime, we can make code
changes on the fly without recompiling and redeploying our web
application. This can make it very easy to test web applications,
because usually the most painful part of web application
development is the wait time between deployment to the servlet
container and testing.
Configuring Your Web Application for Jython Servlets
----------------------------------------------------
Very little needs to be done in any web application to make it
compatible for use with Jython servlets. Jython contains a built-in
class named *PyServlet* that facilitates the creation of Java
servlets using Jython source files. We can make use of PyServlet
quite easily in our application by adding the necessary XML
configuration into the application’s web.xml descriptor such that
the *PyServlet* class gets loaded at runtime and any file that
contains the *.py* suffix will be passed to it. Once this
configuration has been added to a web application, and *jython.jar*
has been added to the CLASSPATH then the web application is ready
to use Jython servlets. See Listing 13-1.
*Listing 13-1. Making a Web Application Compatible with Jython*
::
PyServletorg.python.util.PyServlet1PyServlet*.py
Any servlet that is going to be used by a Java servlet container
also needs to be added to the *web.xml* file as well, since this
allows for the correct mapping of the servlet via the URL. For the
purposes of this book, we will code a servlet named
*NewJythonServlet* in the next section, so the following XML
configuration will need to be added to the web.xml file. See
Listing 13-2.
*Listing 13-2. Coding a Jython Servlet*
::
NewJythonServletNewJythonServletNewJythonServlet/NewJythonServlet
Writing a Simple Servlet
------------------------
In order to write a servlet, we must have the
*javax.servlet.http.HttpServlet* abstract Java class within our
CLASSPATH so that it can be extended by our Jython servlet to help
facilitate the code. This abstract class, along with the other
servlet implementation classes, is part of the *servlet-api.jar*
file. According to the abstract class, there are two methods that
we should override in any Java servlet, those being *doGet* and
*doPost*. The former performs the HTTP GET operation while the
latter performs the HTTP POST operation for a servlet. Other
commonly overridden methods include *doPut*, *doDelete*, and
*getServletInfo*. The first performs the HTTP PUT operation, the
second performs the HTTP DELETE operation, and the last provides a
description for a servlet. In the following example, and in most
use-cases, only the *doGet* and *doPost* are used.
Let’s first show the code for an extremely simple Java servlet.
This servlet contains no functionality other than printing its name
along with its location in the web application to the screen.
Following that code we will take a look at the same servlet coded
in Jython for comparison (Listing 13-3).
*Listing 13-3. NewJavaServlet.java*
::
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class NewJavaServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("");
out.println("
")
def getServletInfo(self):
return "Short Description"
Not only is the concise code an attractive feature, but also the
easy development lifecycle for working with dynamic servlets. As
stated previously, there is no need to redeploy each time you make
a change because of the compile at runtime that Jython offers.
Simply change the Jython servlet, save, and reload the webpage to
see the update. If you begin to think about the possibilities
you’ll realize that the code above is just a basic example, you can
do anything in a Jython servlet that you can with Java and even
most of what can be done using the Python language as well.
To summarize the use of Jython servlets, you simply include
*jython.jar* and *servlet-api.jar* in your CLASSPATH. Add necessary
XML to the web.xml, and then finally code the servlet by extending
the javax.servlet.http.HttpServlet abstract class.
Using JSP with Jython
---------------------
Harnessing Jython servlets allows for a more productive development
lifecycle, but in certain situations Jython code may not be the
most convenient way to deal with front-facing web code. Sometimes
using a markup language such as HTML works better for developing
sophisticated front-ends. For instance, it is easy enough to
include JavaScript code within a Jython servlet. However, all of
the JavaScript code would be written within the context of a
String. Not only does this eliminate the usefulness of an IDE for
situations such as semantic code coloring and auto completion, but
it also makes code harder to read and understand. Cleanly
separating such code from Jython or Java makes code more clear to
read, and easier to maintain in the long run. One possible solution
would be to choose from one of the Python template languages such
as Django, but using Java Server Pages (JSP) technology can also be
a nice solution.
Using a JSP allows one to integrate Java code into HTML markup in
order to generate dynamic page content. We are not fans of JSP.
There, we said it: JSP can make code a living nightmare if the
technology is not used correctly. Although JSP can make it very
easy to mix JavaScript, HTML, and Java into one file, it can make
maintenance very difficult. Mixing Java code with HTML or
JavaScript is a bad idea. The same would also be true for mixing
Jython and HTML or JavaScript.
The Model-View-Controller (MVC) paradigm allows for clean
separation between logic code, such as Java or Jython, and markup
code such as HTML. JavaScript is always gets grouped into the same
arena as HTML because it is a client-side scripting language. In
other words, JavaScript code should also be separated from the
logic code. In thinking about MVC, the controller code would be the
markup and JavaScript code used to capture data from the end-user.
Model code would be the business logic that manipulates the data.
Model code is contained within our Jython or Java. The view would
be the markup and JavaScript displaying the result.
Clean separation using MVC can be achieved successfully by
combining JSP with Jython servlets. In this section we will take a
look at a simple example of how to do so. As with many of the other
examples in this text it will only brush upon the surface of great
features that are available. Once you learn how to make use of JSP
and Jython servlets you can explore further into the technology.
Configuring for JSP
~~~~~~~~~~~~~~~~~~~
There is no real configuration above and beyond that of configuring
a web application to make use of Jython servlets. Add the necessary
XML to the web.xml deployment descriptor, include the correct JARs
in your application, and begin coding. What is important to note is
that the *.py* files that will be used for the Jython servlets must
reside within your CLASSPATH. It is common for the Jython servlets
to reside in the same directory as the JSP web pages themselves.
This can make things easier, but it can also be frowned upon
because this concept does not make use of packages for organizing
code. For simplicity sake, we will place the servlet code into the
same directory as the JSP, but you can do it differently.
Coding the Controller/View
~~~~~~~~~~~~~~~~~~~~~~~~~~
The view portion of the application will be coded using markup and
JavaScript code. Obviously, this technique utilizes JSP to contain
the markup, and the JavaScript can either be embedded directly into
the JSP or reside in separate *.js* files as needed. The latter is
the preferred method in order to make things clean, but many web
applications embed small amounts of JavaScript within the pages
themselves.
The JSP in this example is rather simple, there is no JavaScript in
the example and it only contains a couple of input text areas. This
JSP will include two forms because we will have two separate submit
buttons on the page. Each of these forms will redirect to a
different Jython servlet, which will do something with the data
that has been supplied within the input text. In our example, the
first form contains a small textbox in which the user can type any
text that will be redisplayed on the page once the corresponding
submit button has been pressed. Very cool, eh? Not really, but it
is of good value for learning the correlation between JSP and the
servlet implementation. The second form contains two text boxes in
which the user will place numbers; hitting the submit button in
this form will cause the numbers to be passed to another servlet
that will calculate and return the sum of the two numbers. Listing
13-5 is the code for this simple JSP.
*Listing 13-5. JSP Code for a Simple Controller/Viewer Application*
*testJSP.jsp*
::
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
Jython JSP Test
${page_text}
In this JSP example, you can see that the first form redirects to a
Jython servlet named
*add_to_page.py, which plays the role of the controller*. In this
case, the text that is contained within the input textbox named *p*
will be passed into the servlet, and redisplayed in on the page.
The text to be redisplayed will be stored in an attribute named
*page_text*, and you can see that it is referenced within the JSP
page using the ${} notation. Listing 13-6 is the code for
*add_to_page.py*.
*Listing 13-6. A Simple Jython Controller Servlet*
::
#######################################################################
# add_to_page.py
#
# Simple servlet that takes some text from a web page and redisplays
# it.
#######################################################################
import java, javax, sys
class add_to_page(javax.servlet.http.HttpServlet):
def doGet(self, request, response):
self.doPost(request, response)
def doPost(self, request, response):
addtext = request.getParameter("p")
if not addtext:
addtext = ""
request.setAttribute("page_text", addtext)
dispatcher = request.getRequestDispatcher("testJython.jsp")
dispatcher.forward(request, response)
Quick and simple, the servlet takes the request and obtains value
contained within the parameter *p*. It then assigns that value to a
variable named *addtext*. This variable is then assigned to an
attribute in the request named *page_text* and forwarded back to
the *testJython.jsp* page. The code could just as easily have
forwarded to a different JSP, which is how we’d go about creating a
more in-depth application.
The second form in our JSP takes two values and returns the
resulting sum to the page. If someone were to enter text instead of
numerical values into the text boxes then an error message would be
displayed in place of the sum. While very simplistic, this servlet
demonstrates that any business logic can be coded in the servlet,
including database calls, and so on. See Listing 13-7.
*Listing 13-7. Jython Servlet Business Logic*
::
#######################################################################
# add_numbers.py
#
# Calculates the sum for two numbers and returns it.
#######################################################################
import javax
class add_numbers(javax.servlet.http.HttpServlet):
def doGet(self, request, response):
self.doPost(request, response)
def doPost(self, request, response):
x = request.getParameter("x")
y = request.getParameter("y")
if not x or not y:
sum = "You must place numbers in each value box"
else:
try:
sum = int(x) + int(y)
except ValueError, e:
sum = "You must place numbers only in each value box"
request.setAttribute("sum", sum)
dispatcher = request.getRequestDispatcher("testJython.jsp")
dispatcher.forward(request, response)
If we add the JSP and the servlets to the web application we
created in the previous Jython Servlet section, then this example
should work out-of-the-box.
It is also possible to embed code into Java Server Pages by using
various template tags known as scriptlets to enclose the code. In
such cases, the JSP must contain Java code unless a special
framework such as the Bean Scripting Framework
(http://jakarta.apache.org/bsf/) is used along with JSP. For more
details on using Java Server Pages, please take a look at the Sun
Microsystems JSP documentation
(http://java.sun.com/products/jsp/docs.html) or pick up a book such
as
*Beginning JSP, JSF and Tomcat Web Development: From Novice to Professional* from
Apress.
Applets and Java Web Start
==========================
At the time of this writing, applets in Jython 2.5.0 are not yet an
available option. This is because applets must be statically
compiled and available for embedding within a webpage using the
*