Skip to main content

Create VoiceXML pages within a Java Web developer framework

Generate VoiceXML using Java servlets and JSPs

Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc.
Photo of Brett McLaughlin
Brett McLaughlin has worked in computers since the Logo days. (Remember the little triangle?) In recent years, he's become one of the most well-known authors and programmers in the Java and XML communities. He's worked for Nextel Communications, implementing complex enterprise systems; at Lutris Technologies, actually writing application servers; and most recently at O'Reilly Media, Inc., where he continues to write and edit books that matter. Brett's upcoming book, Head Rush Ajax, brings the award-winning and innovative Head First approach to Ajax, along with bestselling co-authors, Eric and Beth Freeman. His last book, Java 1.5 Tiger: A Developer's Notebook, was the first book available on the newest version of Java technology. And his classic Java and XML remains one of the definitive works on using XML technologies in the Java language.

Summary:  For most Web developers, the task of outputting HTML, XHTML, or even XML is a trivial one: it's just part of the everyday process of creating and deploying Web applications. While it seems a tremendous leap to move from displaying pages on the Internet to answering and responding to telephone calls, it really isn't. In this article, you'll see that the same techniques that allow you to create Web pages dynamically can also let you pick up the (virtual) phone and answer calls.

Date:  17 Jan 2006
Level:  Intermediate
Activity:  5091 views

Over the last five years, the Web has been stretched perhaps further than at any other time in its history. What was once a largely text-based medium for software programs called "Web browsers" has become an information source for any device that has connectivity. Initially, mobile phones joined the list of devices that could access Web pages, followed by pagers, handheld devices, personal planners, and anything else that could make a wireless connection to the Web. In more recent years, telephony has entered this fray, and the desire to make Web programs accessible over normal phone lines has come into vogue.

This last category of applications -- where a user accesses an online service through a telephone -- is better called a telephone application. Since phones obviously can't be used to "click on a link," application interactions are almost all handled by voice. Instead of clicking a link, a user says "Account Information," or uses the keypad following pre-recorded instructions.

The ability to serve telephones through existing -- or slightly modified -- Web applications is a powerful idea, and one that many Web developers are eager to explore. The most important thing to know about Web and phone applications is that you can use virtually the same technology stack to create both. HTML, XHTML, and XML are three of the most common technologies underlying Web interfaces, and VoiceXML (or VXML) is a closely related technology that makes Web interactions available to phone clients. JavaServer Pages and servlets, PHP scripts, and Ruby applications can all respond to phone requests as easily as those that come in over a handheld or Web browser. In this article, I focus on using the Java platform to serve simple VoiceXML applications, but you can apply much of the discussion equally to PHP, Perl, or your programming language of choice.

VoiceXML, CCXML, or CallXML?

Get started with Voxeo!

You'll need to create a free Voxeo developer account to follow the exercises in this article. While Voxeo isn't a required service for VoiceXML, it does provide a nice set of tools, as well as thousands of pages of VoiceXML, CallXML, and CCXML documentation. This article serves as much as an introduction to Voxeo as to VoiceXML programming, and you can expect to hear even more from developerWorks about Voxeo in the future.

The most commonly used standard for building voice applications is VoiceXML. Most VXML browsers support VoiceXML 2.0, which is the VXML version used throughout this article. VXML is W3C-specification-compliant and rapidly expanding, but still catching up with v2.1. VXML 3.0 is also on the horizon.

CCXML stands for Call Control XML, and is the newest player that meets the W3C specifications for telephony markup. CCXML is more advanced than most VoiceXML implementations, offering support for callbacks, event listeners, and multi-line and multi-party sessions. Unless you specifically need these features, however, you're probably best served by sticking with VoiceXML, which is more stable and in widespread use.

CallXML is a platform specific to Voxeo. CallXML is extremely easy to learn and provides great support for touchtone input (note that it does not support voice recognition). CallXML's big downside is that it is vendor-specific. While Voxeo is a great site with a ton of resources, it's never a good idea to get locked into a specific vendor. Again, most developers will find that VoiceXML meets their needs.


VoiceXML 101

Before getting into the Java side of the VoiceXML picture, you should have a basic understanding of how a VoiceXML application works. To that end, I'll take you quickly through a very simple VoiceXML application. The example app will get you used to seeing VXML files, as well as ensuring you have access to (and can use) the Voxeo call-assignment service, which is crucial to the rest of this article.

A simple VXML page

VoiceXML begins with at least one VXML file, the VoiceXML-flavored version of XML used to inform telephony applications of what they should (and can) do. Listing 1 is a very simple VXML file. Save this file on your local machine (you can download the complete example source code from Download, but you should get used to working with these files yourself, anyway).


Listing 1. A very simple VXML file



<?xml version="1.0" encoding="UTF-8"?>

<vxml version="2.1">
  <form>
    <block>
      <prompt>
        Things are working correctly! Congratulations.
      </prompt>
    </block>
  </form>
</vxml>


This is about as basic as VoiceXML gets; if you're unclear on the syntax check out some of the other VoiceXML articles listed in Resources. The VXML file in Listing 1 consists of a single prompt and doesn't offer any interactivity; you'll see much more advanced uses of VoiceXML in the sections on working with Java code. For now, use this simple test case to ensure your environment is working correctly.

Upload the application

Next, put your VXML file somewhere publicly accessible. If you have an ISP, just upload the VXML file to your Web site; you might want to create a directory for your VoiceXML files off of your Web root, like /voicexml or /voice. Make sure the directory and file are Web accessible (consult your system administrator or ISP if you're unclear on how to do this).

In the event that you don't have access to an ISP, you can sign up at Voxeo to use the site's File Manager. You should already have created a Voxeo account, and it comes with 10 MB of hosting space, so this is a nice free option. (Ten MB is a lot of VXML files!)

Once your VXML app is online, you might want to ensure you can access it by entering the URL into your Web browser. Depending on your browser, you might be asked to download the XML file, or see it rendered in some form by your browser. This is just a test to ensure the VXML is available, so don't be concerned if your computer doesn't start speaking to you. Once the VXML is online, you're ready to link it to a phone number.

Assign a phone number to your application

Last call for Voxeo!

If you haven't signed up for a Voxeo account yet, now's the time. You'll need Voxeo tools to follow the examples from here on. Creating an account is free, with no obligation, and you get great tools and support. Go ahead and sign up for a developer account now!

Unlike traditional Web applications, you can't just open up a Web browser and surf on over to your VXML file; at least, not if you want a voice response. To test out a phone-based application, you obviously need a phone, and that implies a number to call. There are plenty of high-dollar approaches to mapping numbers to VoiceXML applications, but for testing, staging, and development, Voxeo offers a great free mapping service.

Navigate over to Voxeo.com, log in (using the fields on the upper left side of the page). Under Account menu, select Application Manager, as shown in Figure 1.


Figure 1. Getting to the Voxeo Application Manager
Select the Application Manager option

Choose Add Application, and then select VoiceXML 2.0 as your development platform.

Next, provide the URL for your VXML file, as well as a name for your application; you can use anything you want for the name, as it's for your own reference. Figure 2 shows the settings to access my VXML file. From the Application Phone Number drop-down list, choose the Staging option. This assigns a temporary staging phone number to the application, so you can actually call in from your own telephone.


Figure 2. Mapping a VXML file to a phone number
Give Voxeo your application's URL and a name

Click Create Application and Voxeo will assign several phone numbers to your application. Figure 3 shows the resulting screen (scrolled down a bit), with all the different access points to the VXML file.


Figure 3. A successful mapping!
Voxeo provides multiple ways to access your application

This feature alone is worth the time it takes to sign up for Voxeo; you can now access your VXML file through a toll number, an 800-number, and Skype, just to list a few. This is nice, since you don't have to use the Voxeo tools to test your application. Even better, you can let your boss test things out without needing an account on the Voxeo site!

Test out the application

All that's left is to call one of the numbers that Voxeo supplies. Once you dial, your VXML application should pick up, and let you know (in an unexciting mechanical voice) that "Things are working correctly! Congratulations."

And that's it: in about five minutes, you had your phone talking to an XML file. Now you're ready to get into some Java code, and learn about generating VXML dynamically.


Java and VXML

At this point, most Java developers try to hand-code VXML from within their Java servlets, add in hundreds of out.println() statements, worry about the content type of the output, and generally add a lot of unnecessary complexity to many applications. Before you begin those more complex programming tasks -- all of which are useful when used properly -- get your feet wet with some very basic VoiceXML servlet programming in this section.

Prototyping a VXML file

To begin with, develop your VXML file. Don't open up an IDE or start coding Java; instead, just fire up a text editor, and resist the urge to immediately add package and import statements. Instead, build a simple VXML file, much as you did earlier in this article.

For example, Listing 2 is another pretty basic VXML file. It's a voice-recognition VXML file that takes in a favorite instrument and offers some commentary on the caller's choices.


Listing 2. Another basic VXML file



<?xml version="1.0" encoding="UTF-8"?>

<vxml version="2.1">
  <form id="MainMenu">
    <field name="instrument">
      <prompt>What is your  favorite musical instrument?</prompt>

      <!-- Insert an inline grammar -->
      <grammar type="text/gsl">
        [guitar mandolin dobro (violin fiddle) banjo]
      </grammar>

      <!-- Handle the case when they give no answer -->
      <noinput>
        Did you say something? I didn't hear you.
        <reprompt />
      </noinput>

      <!-- Handle the case when no match is found -->
      <nomatch>
        I suppose that's OK, but it's not on my top five. 
        Want to try again?
        <reprompt />
      </nomatch>
    </field>

    <!-- Handle the various options. -->
    <filled namelist="instrument">
      <if cond="instrument == 'guitar'">
        <prompt>That's right! Hang up and go practice.</prompt>
      <elseif cond="instrument == 'mandolin'" />
        <prompt>Nice... and only four strings to keep in tune.</prompt>
      <elseif cond="instrument == 'dobro'" />
        <prompt>Boy, that's no fun to learn, is it?</prompt>
      <elseif cond="instrument == 'violin'" />
        <prompt>We call that a fiddle, Mr. Fancy Pants.</prompt>
      <elseif cond="instrument == 'fiddle'" />
        <prompt>Does playing classical music on a 
        fiddle make it a violin?</prompt>
      <elseif cond="instrument == 'banjo'" />
        <prompt>Wow, I hope you live alone.</prompt>
      </if>
    </filled>
  </form>
</vxml>



Write this VXML, save it, upload it to your ISP, and assign a number to it. Only after you do all of these steps -- ensuring that your VXML works -- are you ready to even begin thinking about coding Java.

If you jump right into Java, you'll probably make mistakes in your output, as well as mistakes in your code. The result is trying to simultaneously debug a VXML file (XML) and a servlet (Java), all within a Web framework, which is notoriously hard to debug in the first place. Rather than add all these variables -- no pun intended -- ensure that you start with a working VXML file. Then you're ready to get your Java code running.

Reading in the file

With your VXML ready to use, you're finally set to get into some code. First, begin with a servlet that simply loads the VXML file. Listing 3 is a servlet that does just that -- loads up the VXML developed in Listing 2. There's no output, so don't expect much yet.


Listing 3. Loading a VXML file



package com.ibm.vxml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

public class VoiceXMLServlet extends HttpServlet {

  private static final String VXML_FILENAME =
    "simple-voice_recog.xml";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    String vxmlDir = getServletContext().getInitParameter("vxml-dir");

    BufferedInputStream bis = null;
    ServletOutputStream out = null;

    try {
      // Load the VXML file
      File vxml = new File(vxmlDir + "/" + VXML_FILENAME);
      FileInputStream fis = new FileInputStream(vxml);
      bis = new BufferedInputStream(fis);

      // Output the VXML file 
      int readBytes = 0;
      while ((readBytes = bis.read()) != -1) {
        // output the VXML
      }
    } finally {
      if (out != null) out.close();
      if (bis != null) bis.close();
    }
  }
}


This code is pretty straightforward. It loads up an XML file -- specified through a directory in the servlet's configuration context and a constant filename -- and then iterates over the content of that file. You might hard-code the file's path in the servlet, but it's a much better idea to store at least the directory name in your Web.xml file, located in the WEB-INF/ directory of your servlet's context. Listing 4 shows the context parameter in Web.xml.


Listing 4. The context parameter for the servlet


  <context-param>
    <param-name>vxml-dir</param-name>
    <param-value>/path-to-your-voicexml-dir/voicexml</param-value>
  </context-param>



If you compile your servlet and try to load it in a Web browser, you'll only get a blank screen; still, you should make sure you get at least that. If you get any errors you'll need to correct them. For example, it's common to run into file-access problems or typos in the VXML file path. Once you get a blank screen, you're ready to actually output the VXML file.

Outputting VXML from a servlet

First, you need to get access to an output object, so you can send content to the browser. This is easy enough:

      
// Load the VXML file
      File vxml = new File(vxmlDir + "/" + VXML_FILENAME);
      FileInputStream fis = new FileInputStream(vxml);
      bis = new BufferedInputStream(fis);

      // Let the browser know that XML is coming
      out = res.getOutputStream();


Spitting out the content from the file itself is easy; you just use a single line of code:

      
// Output the VXML file 
      int readBytes = 0;
      while ((readBytes = bis.read()) != -1) {
        // output the VXML
        out.write(readBytes);
      }


While this might look like it's enough, you still need to let the browser know that you're sending XML to it. Remember, browsers are used to HTML, and some don't happily accept XML. You can set the content type, as well as the length of that content, by using the HttpServletResponse object again:

     
 // Let the browser know that XML is coming
      out = res.getOutputStream();
      res.setContentType("text/xml");
      res.setContentLength((int)vxml.length());

Listing 5 shows all of this code added into the servlet you saw back in Listing 3.


Listing 5. The VoiceXMLServlet, completed and ready to load VXML files



package com.ibm.vxml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

public class VoiceXMLServlet extends HttpServlet {

  private static final String VXML_FILENAME =
    "simple-voice_recog.xml";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    String vxmlDir = getServletContext().getInitParameter("vxml-dir");

    BufferedInputStream bis = null;
    ServletOutputStream out = null;

    try {
      // Load the VXML file
      File vxml = new File(vxmlDir + "/" + VXML_FILENAME);
      FileInputStream fis = new FileInputStream(vxml);
      bis = new BufferedInputStream(fis);

      // Let the browser know that XML is coming
      out = res.getOutputStream();
      res.setContentType("text/xml");
      res.setContentLength((int)vxml.length());

      // Output the VXML file 
      int readBytes = 0;
      while ((readBytes = bis.read()) != -1) {
        // output the VXML
        out.write(readBytes);
      }
    } finally {
      if (out != null) out.close();
      if (bis != null) bis.close();
    }
  }
}

Testing servlet-loaded VoiceXML

Compile your servlet with these changes, and restart your servlet engine if you need to. Browse to the servlet, and you should see output similar to Figure 4. Success!


Figure 4. The VoiceXML servlet outputting VXML
Most browsers will give you some sort of XML rendering of your VXML file

If you don't get output like this, try to ensure that your file is where you indicated it to be, and that you don't have any permission issues. You might also check your servlet engine's logs, or ask a system administrator for help.

Now you're ready to map a phone number to your servlet. Head back over to Voxeo.com's Application Manager and add a new application (you'll probably see the applications you worked with earlier). Make sure you select VoiceXML 2.0, and then enter a name for the new application and the URL for your servlet. Voxeo will create your application and assign it a phone number.

Dial in to this new number and you should hear the prompt from the VXML back in Listing 2. Congratulations! You've just coded a Java servlet that outputs VXML, and hooked a phone number into it.

Some optional additions

You might want to make a couple minor additions to your servlet code. Neither are required, but both add a bit of robustness and documentation to the existing version.

First, you might want to allow users to access the VXML through a POST request. This could occur if a user clicked a button on a form, and that form made a POST request to the VoiceXMLServlet. It's a pretty simple operation to handle in the servlet; just write a version of doPost() that delegates to the doGet() method you already have, as shown here:

  
public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    doGet(req, res);
  }


Another simple addition is to actually let browsers know that you're outputting the content of a VXML file. To do this, set the Content-disposition response header in your servlet, like so:

      
// Let the browser know that XML is coming
      out = res.getOutputStream();
      res.setContentType("text/xml");
      res.setContentLength((int)vxml.length());
      res.addHeader("Content-Disposition",
        "attachment; filename=" + vxml);


Now browsers (or other code) reading your response can discover the VXML file that was served. Be sure not to include your complete file path, though; that is a security risk!


Dynamic VoiceXML

Once you have a servlet that outputs a VXML file, it's a pretty small task to move from that -- using the code as a model or template -- to a servlet that outputs VXML dynamically. In other words, you can move away from simply loading a static VXML file, and start programmatically creating VXML.

The Java platform really begins to shine when you get into dynamic VoiceXML. It provides the ability to easily output XML, as well as interact with databases, directory servers, authentication stores, and sessions. As it turns out, building dynamic VXML gets rid of some of the formality of voice-based systems, as well.

In this section, I walk you through creating a Java servlet that outputs dynamic VXML.

Outputting VXML through out.println()

You've already seen how to get access to the ServletOutputStream, and then insert bytes into that output stream. However, dealing directly with bytes isn't nearly as manageable when you're not just transferring bytes from a source (like a static VXML file) to an output stream.

In cases where you want to create the VXML on your own, you're better off working with a PrintWriter. You can push entire strings out with that class, making it much more useful for creating and outputting dynamic content. It only requires a small change to your code, as shown below.

  
public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    String vxmlDir = getServletContext().getInitParameter("vxml-dir");

    BufferedInputStream bis = null;
    ServletOutputStream out = null;

    try {
      // Load the VXML file
      File vxml = new File(vxmlDir + "/" + VXML_FILENAME);
      FileInputStream fis = new FileInputStream(vxml);
      bis = new BufferedInputStream(fis);

      // Let the browser know that XML is coming
      PrintWriter out = res.getOutputStream();
      res.setContentType("text/xml");
      res.setContentLength((int)vxml.length());

      // Output content using PrintWriter
    } finally {
      if (out != null) out.close();
      if (bis != null) bis.close();
    }
  }


Don't forget to also import the java.io.PrintWriter class: it's not automatically available to your servlet's code base.

With a PrintWriter, you can now output string-based content. For example, Listing 6 outputs the same VXML you saw back in Listing 1, except through a servlet, and without loading the VXML content from a static file.


Listing 6. Dynamically outputting VXML



package com.ibm.vxml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;

public class DynamicVoiceXMLServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    BufferedInputStream bis = null;
    PrintWriter out = null;

    try {
      // Let the browser know that XML is coming
      out = res.getWriter();
      res.setContentType("text/xml");

      // Output VXML
      out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
      out.println("<vxml version=\"2.1\">");
      out.println(" <form><block><prompt>");
      out.println("  Things are working correctly! Congratulations.");
      out.println(" </prompt></block></form>");
      out.println("</vxml>");

    } finally {
      if (out != null) out.close();
      if (bis != null) bis.close();
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    doGet(req, res);
  }
}


You can compile this servlet, register it with Voxeo, and access it by phone, just as you did with Listing 1. Now let's move on to some examples that show off the dynamic programming capabilities of a language like Java.

Adding in time-awareness

One of the simplest things you can do with servlet-based VXML output is add some awareness of time. It's trivial to grab the current time and date with Java code, so that's a great place to start.

Using the Calendar class you can easily get the hour of the day (or anything else related to the current date, really). Listing 7 demonstrates code to get a new instance of the Calendar class, obtain the hour of the day (which is returned in a 24-hour format), and then put together a simple greeting based on that hour.


Listing 7. Dynamically outputting VXML



package com.ibm.vxml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import javax.servlet.*;
import javax.servlet.http.*;

public class DynamicVoiceXMLServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    BufferedInputStream bis = null;
    PrintWriter out = null;

    try {
      // Let the browser know that XML is coming
      out = res.getWriter();
      res.setContentType("text/xml");

      // Output VXML
      out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
      out.println("<vxml version=\"2.1\">");
      out.println(" <form><block><prompt>");

      // Output a greeting based on the time of day
      Calendar cal = Calendar.getInstance();
      int hour = cal.get(Calendar.HOUR_OF_DAY);
      if (hour < 6) {
        out.println("You're up early. Good morning.");
      } else if (hour < 12) {
        out.println("Good morning. How's your day so far?");

      } else if (hour < 18) {
        out.println("Half the day is done... good afternoon!");
      } else{
        out.println("Hope you are enjoying your evening.");
      }

      out.println(" </prompt></block></form>");
      out.println("</vxml>");

    } finally {
      if (out != null) out.close();
      if (bis != null) bis.close();
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    doGet(req, res);
  }
}

Differences between callers and VXML generators

Listing 7 also showcases another feature of VoiceXML and dynamically generated VXML: the possible disparity between the caller and the VXML itself. For instance, suppose a user living in New Zealand calls into the application shown in Listing 7. If it's 10:00 PM in New Zealand, but the server outputting the VXML is in Denver, Colorado, they'll probably be greeted with an odd message, such as "You're up early. Good morning." That's hardly appropriate, and it could get worse: if you've added in greetings for specific days of the week, you're really going to have some mismatches.

The basic problem stems from the VXML and Java running in the locale and time zone of a specific server, but being available to callers from all over the world. If your servlet doesn't take this into account, you're going to have some rather confused callers. You have several options:

  • Ignore the difference and hope callers understand that your server just isn't running code in their time zone.
  • Explicitly state that times and dates are local to the server; for instance, your afternoon greeting might be, "It's afternoon here. I hope you're having a nice day as well."
  • Write code that asks for a time zone or the offset from GMT, and then develop greetings based on that information.

Unfortunately, none of these turns out to be an attractive option. The first does just what it says: basically ignores the caller. It should go without saying that ignoring callers is not the way to get and maintain a business. The second idea -- stating the local time and explicitly noting that it's local -- is not much more helpful, as it still tends to ignore the caller; it's just a little more considerate in the process.

The final option might seem at first to be attractive; it's easy to write VXML to allow the user to supply a number offset from GMT, and then respond based on that. However, callers tend to like to get to information as quickly as possible; the more response prompts you have, the greater risk of annoying your callers and having them hang up unsatisfied. Therefore, unless you are providing a time- or date-based service, requiring a caller to indicate the time zone is a waste of one of those prompts. Even worse, many callers don't know their offset from GMT, so you're faced with supporting time zones, time zone abbreviations, daylight savings time ... the list can get long and unwieldy.

Why bother, then?

So why even play with date-based VXML generation? Largely because it illustrates these very issues! You need to be very conscious of your audience, and try and give them information that is relevant to them, not to your server or your locality.

In the case of date-based processing, the lesson is that you should probably employ a final, better option for dealing with callers and avoid date- and time-based transactions altogether, unless absolutely necessary. If you expect callers from outside your time zone, you're just asking for trouble by trying to provide a time-related feature. The same principles apply for any data that might change across state, country, or continental lines.

Finally, there are obviously plenty of times when using a servlet for outputting VXML is not that great of an idea. If you're just spitting out VXML from a static file, you gain very little (perhaps a bit of flexibility), but adding code, compilation, debugging, a servlet engine, and a lot more to the complexity of your voice app. In these simple cases, stick with using static VXML files.


Some interesting ideas

As you've seen so far in this article, sometimes a servlet-generated VXML does not make sense. Before finishing up, though, consider several cases where using a language like Java is a great telephone application solution. I won't provide full examples here, but look for them in future articles.

Loading VXML from a database

The most obvious application of Java concerning VoiceXML is using a database to feed a dynamic VXML output. This is probably what many of you expected to learn about when you began this article (although you wouldn't have learned as many lessons if that was the core example). In any case, JDBC makes it simple to connect to a database, and then use results from SQL queries to populate VXML.

For example, you could develop a table that contained all the grammar information for your VXM, and then load that grammar into each VXML file you output. Rather than having to code grammar for each and every VXML file, you can share a grammar between similar files. Even better, you can pre-load these grammars across all servlets, or instances of a particular servlet, and have the benefit of storing your grammars in a database without paying the cost for loading that grammar on each and every request.

Loading VXML based on user credentials

Another nice Java feature -- particularly as it relates to servlets, JSPs, and Web-based programming -- is the ability to store user credentials in a session. This gets you firmly into authentication and authorization, as well as very highly customized content.

For example, consider a voice application that begins by asking for a user ID number and a PIN (like most banking or financial applications do today). You can authenticate these credentials against a database -- already a notable strength of the Java platform -- and then store the caller's ID into a session variable. Then, each Java servlet or JSP that fields a request from that caller can figure out what options to offer the user based on those credentials.

While plenty of VoiceXML alternatives offer similar functionality, very few boast the ability to share code with Web-based versions of their applications. In other words, the Java platform lets you share not only a database between a VoiceXML and Web-based version of an application, but code components. Your VXML-producing servlets can use the same authentication and permissions utility classes as your HTML- and XHTML-producing servlets; your JSPs that respond to phone calls can share cached database connections with your JSPs that handle HTTP requests. As a result, you end up with an application infrastructure that can handle multiple types of clients, rather than having to create an entire application for each client type.


In conclusion

In this article I barely scratched the surface of the things you can do with VXML and the Java platform. I introduced the process of developing VXML, and then showed you how to integrate Java technology into that process. Along the way I dropped hints as to all kinds of interesting ways you can use Java code to develop rich, dynamic VoiceXML applications.

I also let you see some of the really common ways that VoiceXML developers misuse Java technology in voice applications. Trying to get clever with dates and times, attempting locale-based services, and forgetting about the difference between a server's local time and a caller's local time are sure ways to alienate and frustrate users. Consider Java a tool for VoiceXML, but not a showcase for the Date and Calendar classes.

I'll continue writing about these topics and more in future articles, starting with the principles laid down here and expanding on them. If you want to know more about building rich voice application, developing telephone apps that interact with databases, tracking users, and providing individualized content, keep an eye on this space. Also, go back to Voxeo.com and try getting a servlet or two to serve up your VXML. Then come back here next month for more.



Download

DescriptionNameSizeDownload method
Example code for this articlewa-voicexml.zip1KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Photo of Brett McLaughlin

Brett McLaughlin has worked in computers since the Logo days. (Remember the little triangle?) In recent years, he's become one of the most well-known authors and programmers in the Java and XML communities. He's worked for Nextel Communications, implementing complex enterprise systems; at Lutris Technologies, actually writing application servers; and most recently at O'Reilly Media, Inc., where he continues to write and edit books that matter. Brett's upcoming book, Head Rush Ajax, brings the award-winning and innovative Head First approach to Ajax, along with bestselling co-authors, Eric and Beth Freeman. His last book, Java 1.5 Tiger: A Developer's Notebook, was the first book available on the newest version of Java technology. And his classic Java and XML remains one of the definitive works on using XML technologies in the Java language.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, XML, Java technology
ArticleID=101503
ArticleTitle=Create VoiceXML pages within a Java Web developer framework
publish-date=01172006
author1-email=brett@newInstance.com
author1-email-cc=htc@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers