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 (; 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* :: PyServlet org.python.util.PyServlet 1 PyServlet *.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* :: NewJythonServlet NewJythonServlet NewJythonServlet /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.* :: import; import; 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(""); out.println("Servlet NewJavaServlet Test"); out.println(""); out.println(""); out.println("

Servlet NewJavaServlet at " + request.getContextPath () + "

"); out.println(""); out.println(""); } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override public String getServletInfo() { return "Short description"; } } All commenting has been removed from the code in an attempt to make the code a bit shorter. Now, Listing 13-4 is the equivalent servlet code written in Jython. *Listing 13-4.* :: from javax.servlet.http import HttpServlet class NewJythonServlet (HttpServlet): def doGet(self,request,response): self.doPost (request,response) def doPost(self,request,response): toClient = response.getWriter() response.setContentType ("text/html") toClient.println ("Jython Servlet Test" + "

Servlet Jython Servlet at" + request.getContextPath() + "

") 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="" %> Jython JSP Test


+ = ${sum}
In this JSP example, you can see that the first form redirects to a Jython servlet named *, 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 **. *Listing 13-6. A Simple Jython Controller Servlet* :: ####################################################################### # # # 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* :: ####################################################################### # # # 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 ( is used along with JSP. For more details on using Java Server Pages, please take a look at the Sun Microsystems JSP documentation ( 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 ** or ** tag. The static compiler known as *jythonc***has been removed in Jython 2.5.0 in order to make way for better techniques. Jythonc was good for performing certain tasks, such as static compilation of Jython applets, but it created a disconnect in the development lifecycle as it was a separate compilation step that should not be necessary in order to perform simple tasks such as Jython and Java integration. In a future release of Jython, namely 2.5.1 or another release in the near future, a better way to perform static compilation for applets will be included. For now, in order to develop Jython applets you will need to use a previous distribution including *jythonc* and then associate them to the webpage with the ** or ** tag. In Jython, applets are coded in much the same fashion as a standard Java applet. However, the resulting lines of code are significantly smaller in Jython because of its sophisticated syntax. GUI development in general with Jython is a big productivity boost compared to developing a Java Swing application for much the same reason. This is why coding applets in Jython is a viable solution and one that should not be overlooked. Another option for distributing GUI-based applications on the web is to make use of the Java Web Start technology. The only disadvantage of creating a web start application is that it cannot be embedded directly into any web page. A web start application downloads content to the client’s desktop and then runs on the client’s local JVM. Development of a Java Web Start application is no different than development of a standalone desktop application. The user interface can be coded using Jython and the Java Swing API, much like the coding for an applet user interface. Once you’re ready to deploy a web start application then you need to create a Java Network Launching Protocol (JNLP) file that is used for deployment and bundle it with the application. After that has been done, you need to copy the bundle to a web server and create a web page that can be used to launch the application. In this section we will develop a small web start application to demonstrate how it can be done using the object factory design pattern and also using pure Jython along with the standalone Jython JAR file for distribution. Note that there are probably other ways to achieve the same result and that these are just a couple of possible implementations for such an application. Coding a Simple GUI-Based Web Application ----------------------------------------- The web start application that we will develop in this demonstration is very simple, but they can be as advanced as you’d like in the end. The purpose of this section is not to show you how to develop a web-based GUI application, but rather, the process of developing such an application. You can actually take any of the Swing-based applications that were discussed in the GUI chapter and deploy them using web start technology quite easily. As stated in the previous section, there are many different ways to deploy a Jython web start application. We prefer to make use of the object factory design pattern to create simple Jython Swing applications. However, it can also be done using all .py files and then distributed using the Jython stand-alone JAR file. We will discuss each of those techniques in this section. We find that if you are mixing Java and Jython code then the object factory pattern works best. The JAR method may work best for you if developing a strictly Jython application. Object Factory Application Design ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The application we’ll be developing in this section is a simple GUI that takes a line of text and redisplays it in JTextArea. We used Netbeans 6.7 to develop the application, so some of this section may reference particular features that are available in that IDE. To get started with creating an object factory web start application, we first need to create a project. We created a new Java application in Netbeans named *JythonSwingApp* and then added *jython.jar* and *plyjy.jar* to the classpath. First, create the ** class which will really be the driver for the application. The goal for is to use the Jython object factory pattern to coerce a Jython-based Swing application into Java. This class will be the starting point for the application and then the Jython code will perform all of the work under the covers. Using this pattern, we also need a Java interface that can be implemented via the Jython code, so this example also uses a very simple interface that defines a *start()* method which will be used to make our GUI visible. Lastly, the Jython class named below is the code for our ** driver and the Java interface. The directory structure of this application is as shown in Listing 13-8. *Listing 13-8. Object Factory Application Code* **JythonSwingApp** **** **jythonswingapp** **jythonswingapp.interfaces** ** :: package jythonswingapp; import jythonswingapp.interfaces.JySwingType; import org.plyjy.factory.JythonObjectFactory; public class Main { JythonObjectFactory factory; public static void invokeJython(){ JySwingType jySwing = (JySwingType) JythonObjectFactory .createObject(JySwingType.class, "JythonSimpleSwing"); jySwing.start(); } public static void main(String[] args) { invokeJython(); } } As you can see, ** doesn’t do much else except coercing the Jython module and invoking the *start()* method. In Listing 13-9, you will see the ** interface along with the implementation class that is obviously coded in Jython. *Listing 13-9. Interface and Implementation* ** :: package jythonswingapp.interfaces; public interface JySwingType { public void start(); } ** :: import javax.swing as swing import java.awt as awt from jythonswingapp.interfaces import JySwingType import add_player as add_player import Player as Player class JythonSimpleSwing(JySwingType, object): def __init__(self): self.frame=swing.JFrame(title="My Frame", size=(300,300)) self.frame.defaultCloseOperation=swing.JFrame.EXIT_ON_CLOSE self.frame.layout=awt.BorderLayout() self.panel1=swing.JPanel(awt.BorderLayout()) self.panel2=swing.JPanel(awt.GridLayout(4,1)) self.panel2.preferredSize = awt.Dimension(10,100) self.panel3=swing.JPanel(awt.BorderLayout()) self.title=swing.JLabel("Text Rendering") self.button1=swing.JButton("Print Text", actionPerformed=self.printMessage) self.button2=swing.JButton("Clear Text", actionPerformed=self.clearMessage) self.textField=swing.JTextField(30) self.outputText=swing.JTextArea(4,15) self.panel1.add(self.title) self.panel2.add(self.textField) self.panel2.add(self.button1) self.panel2.add(self.button2) self.panel3.add(self.outputText) self.frame.contentPane.add(self.panel1, awt.BorderLayout.PAGE_START) self.frame.contentPane.add(self.panel2, awt.BorderLayout.CENTER) self.frame.contentPane.add(self.panel3, awt.BorderLayout.PAGE_END) def start(self): self.frame.visible=1 def printMessage(self,event): print "Print Text!" self.text = self.textField.getText() self.outputText.append(self.text) def clearMessage(self, event): self.outputText.text = "" If you are using Netbeans, when you clean and build your project a JAR file is automatically generated for you. However, you can easily create a JAR file at the command-line or terminal by ensuring that the ** module resides within your classpath and using the *java -jar* option. Another nice feature of using an IDE such as Netbeans is that you can make this into a web-start application by going into the project properties and checking a couple of boxes. Specifically, if you go into the project properties and select *Application - Web Start* from the left-hand menu, then check the *Enable Web Start* option then the IDE will take care of generating the necessary files to make this happen. Netbeans also has the option to self sign the JAR file which is required to run most applications on another machine via web start. Go ahead and try it out, just ensure that you clean and build your project again after making the changes. To manually create the necessary files for a web start application, you’ll need to generate two additional files that will be placed outside of the application JAR. Create the JAR for your project as you would normally do, and then create a corresponding JNLP file which is used to launch the application, and an HTML page that will reference the JNLP. The HTML page obviously is where you’d open the application if running it from the web. Listing 13-10 is some example code for generating a JNLP as well as embedding in HTML. *Listing 13-10. JNLP Code for Web Start* *launch.jnlp* :: JythonSwingApp YourName JythonSwingApp JythonSwingApp *launch.html* :: Test page for launching the application via JNLP

Test page for launching the application via JNLP

Launch the application In the end, Java web start is a very good way to distribute Jython applications via the web. Distributing via Standalone JAR ------------------------------- It is possible to distribute a web start application using the Jython standalone JAR option. To do so, you must have a copy of the Jython standalone JAR file, explode it, and add your code into the file, then JAR it back up to deploy. The only drawback to using this method is that you may need to ensure files are in the correct locations in order to make it work correctly, which can sometimes be tedious. In order to distribute your Jython applications via a JAR, first download the Jython standalone distribution. Once you have this, you can extract the files from the *jython.jar* using a tool to expand the JAR such as Stuffit or 7zip. Once the JAR has been exploded, you will need to add any of your *.py* scripts into the *Lib* directory, and any Java classes into the root. For instance, if you have a Java class named *org.jythonbook.Book*, you would place it into the appropriate directory according to the package structure. If you have any additional JAR files to include with your application then you will need to make sure that they are in your classpath. Once you’ve completed this setup, JAR your manipulated standalone Jython JAR back up into a ZIP format using a tool such as those noted before. You can then rename the ZIP to a JAR. The application can now be run using the java “-jar” option from the command line using an optional external *.py* file to invoke your application. :: $ java -jar newStandaloneJar.jar {optional .py file} This is only one such technique used to make a JAR file for containing your applications. There are other ways to perform such techniques, but this seems to be the most straight forward and easiest to do. WSGI and Modjy ============== WSGI, also known as the *Web Server Gateway Interface*, is a low-level API that provides communication between a web server and a web application. Actually, WSGI is a lot more than that and you can actually write complete web applications using WSGI. However, WSGI is more of a standard interface to call python methods and functions. Python PEP 333 specifies the proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers. This section will show you how to utilize WSGI to create a very simple “Hello Jython” application by utilizing *modjy*. Modjy is an implementation of a WSGI compliant gateway/server for Jython, built on Java/J2EE servlets. Taken from the modjy website (, modjy is characterized as follows: .. note:: Jython WSGI applications run inside a Java/J2EE container and incoming requests are handled by the servlet container. The container is configured to route requests to the modjy servlet. The modjy servlet then creates an embedded Jython interpreter inside the servlet container, and loads a configured Jython web application. For instance, a Django application can be loaded via modjy. The modjy servlet then delegates the requests to the configured WSGI application or framework. Lastly, the WSGI response is routed back to the client through the servlet container. Running a Modjy Application in Glassfish ---------------------------------------- To run a modjy application in any Java servlet container, the first step is to create a Java web application that will be packaged up as a WAR file. You can create an application from scratch or use an IDE such as Netbeans 6.7 to assist. Once you’ve created your web application, ensure that *jython.jar* resides in the CLASSPATH as modjy is now part of Jython as of 2.5.0. Lastly, you will need to configure the modjy servlet within the application deployment descriptor (web.xml). In this example, we took the modjy sample application for Google App Engine and deployed it in my local Glassfish environment. To configure the application deployment descriptor with modjy, we simply configure the modjy servlet, provide the necessary parameters, and then provide a servlet mapping. In the configuration file shown in Listing 13-11, note that the modjy servlet class is *com.xhaus.modjy.ModjyServlet*. The first parameter you will need to use with the servlet is named *python.home*. Set the value of this parameter equal to your Jython home. Next, set the parameter *python.cachedir.skip* equal to true. The *app_filename* parameter provides the name of the application callable. Other parameters will be set up the same for each modjy application you configure. The last piece of the web.xml that needs to be set up is the servlet mapping. In the example, we set up all URLs to map to the modjy servlet. *Listing 13-11. Configuring the Modjy Servlet* *web.xml* :: modjy demo application modjy WSGI demo application modjy com.xhaus.modjy.ModjyJServlet python.home /Applications/jython/jython2.5.0/ python.cachedir.skip true app_filename cache_callables 1 reload_on_mod 1 log_level debug 1 modjy /* The demo_app should be coded as shown in Listing 13-12. As part of the WSGI standard, the application provides a function that the server calls for each request. In this case, that function is named *handler*. The function must take two parameters, the first being a dictionary of CGI-defined environment variables. The second is a callback that returns the HTTP headers. The callback function should also be called as follows *start_response(status, response_headers, exx_info=None)*, where status is an HTTP status, response_headers is a list of HTTP headers, and exc_info is for exception handling. Let’s take a look at the ** application and identify the features we’ve just discussed. *Listing 13-12.* :: import sys import string def escape_html(s): return s.replace('&', '&').replace('<', '<').replace('>', '>') def cutoff(s, n=100): if len(s) > n: return s[:n]+ '.. cut ..' return s def handler(environ, start_response): writer = start_response("200 OK", [ ('content-type', 'text/html') ]) response_parts = ''' Modjy demo WSGI application running on Local Server!

Modjy servlet running correctly: jython $version on $platform:

Hello jython WSGI on your local server!

Here are the contents of the WSGI environment

''' environ_str = "" keys = environ.keys() keys.sort() for ix, name in enumerate(keys): if ix % 2: background='#ffffff' else: background='#eeeeee' style = " style='background-color:%s;'" % background value = escape_html(cutoff(str(environ[name]))) or ' ' environ_str = "%s\\n%s%s" % \\ (environ_str, style, name, style, value) environ_str = "%s\\n
" % environ_str response_parts = response_parts + environ_str + '\\n' response_text = string.Template(response_parts) return [response_text.substitute(version=sys.version, platform=sys.platform)] This application returns the environment configuration for the server on which you run the application. As you can see, the page is quite simple to code and really resembles a servlet. Once the application has been set up and configured, simply compile the code into a WAR file and deploy it to the Java servlet container of your choice. In this case, we used Glassfish V2 and it worked nicely. However, this same application should be deployable to Tomcat, JBoss, or the like. Summary ======= There are various ways that we can use Jython for creating simple web-based applications. Jython servlets are a good way to make content available on the web, and you can also utilize them along with a JSP page which allows for a Model-View-Controller situation. This is a good technique to use for developing sophisticated web applications, especially those mixing some JavaScript into the action because it really helps to organize things. Most Java web applications use frameworks or other techniques in order to help organize applications in such a way as to apply the MVC concept. It is great to have a way to do such work with Jython as well. This chapter also discussed creation of WSGI applications in Jython making use of modjy. This is a good low-level way to generate web applications as well, although modjy and WSGI are usually used for implementing web frameworks and the like. Solutions such as Django use WSGI in order to follow the standard put forth for all Python web frameworks with PEP 333. You can see from the section in this chapter that WSGI is also a nice quick way to write web applications, much like writing a servlet in Jython. In the next chapters, you will learn more about using web frameworks available to Jython, specifically Django and Pylons. These two frameworks can make any web developers life much easier, and now that they are available on the Java platform via Jython they are even more powerful. Using a templating technique such as Django can be really productive and it is a good way to design a full-blown web application. Techniques discussed in this chapter can also be used for developing large web applications, but using a standard framework such as those discussed in the following chapter should be considered. There are many great ways to code Jython web applications today, and the options continue to grow!