In the first article in this series, you got your feet wet by programming a servlet-based VoiceXML application. You now should be comfortable with using a servlet to output VXML, as you're about to move a good bit beyond the basics of both VXML and servlet-based VoiceXML applications. You'll learn the ins and outs of applications that have call navigation, which allows users to move to different pages and sections of an application using prompts.
In an even moderately sized file-based VoiceXML application, this often involves developing five, ten, or even twenty different VXML pages. Then, of course, you've got to maintain those files, as well as ensure that their permissions keep them accessible in a VoiceXML application, but safe from prying eyes; you also need to make sure that filenames don't change over time (or, if they do, that all referring links in other files are updated). The end result is not quite a maintenance nightmare, but it can be very close.
By moving to a servlet-based application, you can resolve many of these headaches. A single servlet can manage several VXML sections, or even handle output from several different VXML files on a file system. Permissions issues become almost non-existent, as only the servlet needs to have access to the files. Additionally, your servlet can handle file naming through simple constants, allowing you to change a filename in one location, and have it affect all files that the servlet outputs. And, best of all, you can add dynamic content using the servlet, something that is almost impossible using static VXML files.
A brief refresher on multipage VoiceXML
Before diving into writing servlet-driven multipage applications, you need to be clear on how links and sections are handled in VoiceXML, and specifically in your VXML files. Remember, the servlet is simply the means by which VXML is outputted; if you don't have a firm grasp of VXML, no amount of Java coding prowess is going to help your applications perform or behave well, on mobile devices or telephones.
It's trivial to add a link in your VXML file; you simply use the goto element, which is similar to the a element in HTML. Listing 1 shows a VXML page that does nothing more than offer a link to another VXML page.
Listing 1. Linking from one VXML file to another
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1">
<form>
<block>
<goto next="anotherPage.xml" />
</block>
</form>
</vxml>
|
You could then have the target of that link be a simple file, like the one shown in Listing 2. As long as the file is named anotherPage.xml, it doesn't matter what the content of the target file is.
Listing 2. A very simple VXML file
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1">
<form>
<block>
Welcome to another page.
</block>
</form>
</vxml>
|
Make sure that your VXML pages only link to other VXML pages (or to resources that output VXML, such as VXML-producing servlets). This might seem an obvious point, but because VXML is so similar to HTML and XHTML, it's not uncommon to see VXML that mistakenly points to an HTML page, rather than a VXML document.
Breaking your VXML into sections
Just as you can direct users to a different VXML page, you can direct them to a different section of the current VXML page. Listing 3 shows a menu that lets the user select between different types of music, and then sends them to different sections of the VXML file.
Listing 3. A VXML file with multiple sections
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1">
<link next="#Menu">
<grammar type="text/gsl">[menu begin start (start over)]</grammar>
</link>
<form id="Menu">
<block>
<prompt>Welcome to the Menu.</prompt>
</block>
<field name="TypeOfMusic">
<prompt>What is your favorite type of music?</prompt>
<grammar type="text/gsl">
<![CDATA[[
[blues] {<TypeOfMusic "blues">}
[jazz swing] {<TypeOfMusic "jazz">}
[rap urban (hip hop)] {<TypeOfMusic "hip">}
[rock (rock and roll)] {<TypeOfMusic "rock">}
]]]>
</grammar>
<noinput>
<prompt>I didn't get that. Can you try again?</prompt>
<reprompt />
</noinput>
<nomatch>
<prompt>Try another kind of music.</prompt>
<reprompt />
</nomatch>
</field>
<filled>
<if cond="TypeOfMusic == 'blues'">
<goto next="#Blues" />
<elseif cond="TypeOfMusic == 'jazz'" />
<goto next="#Jazz" />
<elseif cond="TypeOfMusic == 'hip'" />
<goto next="#Hip" />
<elseif cond="TypeOfMusic == 'rock'" />
<goto next="#Rock" />
</if>
</filled>
</form>
<form id="Blues">
<field name="ReturnToMain">
<prompt>
Check out Robert Johnson. It doesn't get any better. For
other ideas, say "Menu".
</prompt>
</field>
</form>
<form id="Jazz">
<field name="ReturnToMain">
<prompt>
Check out Django Reinhardt. It doesn't get any better. For
other ideas, say "Menu".
</prompt>
</field>
</form>
<form id="Hip">
<field name="ReturnToMain">
<prompt>
Sorry, I don't have a clue on this one. For
other ideas, say "Menu".
</prompt>
</field>
</form>
<form id="Rock">
<field name="ReturnToMain">
<prompt>
Check out Jimi Hendrix or Cream. It doesn't get any better. For
other ideas, say "Menu".
</prompt>
</field>
</form>
</vxml>
|
Although this is a fairly long piece of VXML, there's nothing in it that's particularly complicated. If you're not sure what some of these elements do, you'll want to check out some of the beginning VXML articles listed in the Resources section .
In this approach, a main menu is created (the form with an ID of TypeOfMusic), and a prompt is supplied. The user can pick one of several options, and then those options are matched using a standard VoiceXML grammar. Based on the reply, the user is directed to one of several sections. Each of these sections is defined by its own ID on a form element and has its own prompt.
In this simple example, each section has a short prompt and then provides a way to return to the main menu. In more complicated applications, though, you could actually add prompts and sub-options, where each section (like "Blues" or "Rock" in the sample) could direct the user to other sections. In fact, you could theoretically repeat this process ad infinitum, and have hundreds of sections in a VXML file.
Of course, that's just theory. In practice, keeping up with more than two or three levels of sections becomes a maintenance nightmare. However, it's certainly a good idea to put a few related sections together. This simple example could be expanded into at least two VXML files, one for the main menu and one for all the sections for each type of music. Even worse, it could be dismantled into five files: one for the main menu, and one for each type of music. Clearly, that approach involves a lot of maintenance as well. The best approach -- and the one espoused in this article -- is to find a happy medium, using a single file for related groupings.
Before going further into using servlets to drive applications that involve multiple VXML files or sections, you need to understand why you would break up your applications in the first place. As already mentioned, it's possible to develop extremely large (and long) VXML files that provide most of an application's functions in one set of prompts or on one screen. Such long files are akin to phone-in services that ask you to press "112" for stereos used in a home with solid walls, "243" for microwaves used in southwestern states during the winter, and "9828" if you want the automotive department, prefer trucks over vans, and have at least three children. That sounds a bit facetious (and is meant to be tongue-in-cheek), but it's very easy to get carried away and make tons of options available to a user. Instead of following this approach, consider breaking your application up into smaller sections or files, with fewer options at each stage.
For telephony customers, this results in a much more usable application. Instead of having to wade through 8, 10, or 15 options, users are choosing from 3 or 4 major categories. Then, they're often prompted again, with more specific sub-categories. While they may have to enter a few more numbers on their phones, they'll feel like they're making progress toward their goal.
To meet the needs of wireless customers, keeping your application broken into smaller sections becomes critical. Often, on-screen menu choices are presented in a top-to-bottom manner. This means that after the fourth or fifth choice, many wireless screens will require scrolling. Users often don't see the options that aren't on the initial screen, and your application can be unfairly panned, simply because a user didn't want to -- or didn't know to -- scroll down. By using smaller menus, fewer options per section, and ultimately moving to more sections (or files), you're going to please more mobile and wireless users, with only a small amount of additional maintenance cost on the developer end.
Navigation with a servlet-generated VXML file
By now, you should realize that you're going to need a pretty balanced approach to serving VXML content across sections of a file, and across entire VXML pages. As already noted, the longer a VXML file gets -- and it often gets longer because you keep adding new sections to it -- the harder it is to maintain and manage. In many cases, servlets offer a way to get the effect of multiple sections, without the maintenance cost. By having a servlet serve up VXML, you can still provide the client with multisection VXML; but you can segregate your content into more manageable sections. That's the focus of this section.
Organizing large VXML files in a servlet
The most obvious advantage in using a servlet to output VXML is in organization. Refer back to Listing 3, and you'll notice two large sections: the main menu, and then all of the code that handles routing the user. With static VXML, you've got to manage all of this in one large XML file. In a servlet, though, you can break up the VXML into different methods. Take a look at Listing 4, which shows the beginnings of a servlet that outputs the VXML shown in Listing 3.
Listing 4. A servlet with multiple VXML sections
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 SectionServlet 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
printHeader(out);
printMainMenu(out);
printOptions(out);
printFooter(out);
} finally {
if (out != null) out.close();
if (bis != null) bis.close();
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doGet(req, res);
}
private void printHeader(PrintWriter out) throws IOException {
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.println("<vxml version=\"2.1\">");
}
private void printMainMenu(PrintWriter out) throws IOException {
out.println(
" <link next=\"#Menu\">\n" +
" <grammar type=\"text/gsl\">[menu begin start (start over)]</grammar>\n" +
" </link>\n" +
"\n" +
" <form id=\"Menu\">\n" +
" <block>\n" +
" <prompt>Welcome to the Menu.</prompt>\n" +
" </block>\n" +
"\n" +
" <field name=\"TypeOfMusic\">\n" +
" <prompt>What is your favorite type of music?</prompt>\n" +
" <grammar type=\"text/gsl\">\n" +
" <![CDATA[[\n" +
" [blues] {<TypeOfMusic \"blues\">}\n" +
" [jazz swing] {<TypeOfMusic \"jazz\">}\n" +
" [rap urban (hip hop)] {<TypeOfMusic \"hip\">}\n" +
" [rock (rock and roll)] {<TypeOfMusic \"rock\">}\n" +
" ]]]>\n" +
" </grammar>\n" +
"\n" +
" <noinput>\n" +
" <prompt>I didn't get that. Can you try again?</prompt>\n" +
" <reprompt />\n" +
" </noinput>\n" +
" <nomatch>\n" +
" <prompt>Try another kind of music.</prompt>\n" +
" <reprompt />\n" +
" </nomatch>\n" +
" </field>\n" +
"\n" +
" <filled>\n" +
" <if cond=\"TypeOfMusic == 'blues'\">\n" +
" <goto next=\"#Blues\" />\n" +
" <elseif cond=\"TypeOfMusic == 'jazz'\" />\n" +
" <goto next=\"#Jazz\" />\n" +
" <elseif cond=\"TypeOfMusic == 'hip'\" />\n" +
" <goto next=\"#Hip\" />\n" +
" <elseif cond=\"TypeOfMusic == 'rock'\" />\n" +
" <goto next=\"#Rock\" />\n" +
" </if>\n" +
" </filled>\n" +
" </form>");
}
private void printOptions(PrintWriter out) throws IOException {
out.println(
" <form id=\"Blues\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Robert Johnson. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Jazz\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Django Reinhardt. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Hip\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Sorry, I don't have a clue on this one. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Rock\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Eric Clapton. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>");
}
private void printFooter(PrintWriter out) throws IOException {
out.println("</vxml>");
}
}
|
This is a pretty long listing, but don't miss the advantage of this code in its length. It's possible to completely separate out the menu code from the options code, and it's thus easier to maintain the VXML. With code like this, you don't have to deal with a static file; instead, the code can be managed in an IDE or visual environment very easily. You could also break up the printOptions() method into multiple methods as well, like printBluesOption() or printJazzOptions(). You could even get fancy and write a method that takes a parameter and then prints out the appropriate musical VXML advice, called something like printMusicAdvice(String musicType, PrintWriter out). I'll leave this to you as an exercise, but you should see that you can quickly take your VXML and break it up into highly modular sections.
Getting modular with your VXML and servlets
Even better, you could easily move from the setup in Listing 4 to an even more modular approach. For example, instead of keeping all of your VXML as text in the servlet, you could break it out into its own class. Take a look at Listing 5, which takes this idea and puts it into action.
Listing 5. Going modular with your VXML-serving servlet
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 ModularSectionServlet 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
VXMLUtils.printHeader(out);
MusicVXML.printMainMenu(out);
MusicVXML.printOptions(out);
VXMLUtils.printFooter(out);
} finally {
if (out != null) out.close();
if (bis != null) bis.close();
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doGet(req, res);
}
}
|
In this example, all the actual VXML has been relegated to two classes. First, VXMLUtils is a class that handles repetitive VXML tasks. Listing 6 shows this class; it does exactly what the code in Listing 4 did, but now the header and footer of the VXML are broken out from the main servlet code into this utility class.
Listing 6. Using a utility class for common VXML tasks
package com.ibm.vxml;
import java.io.IOException;
import java.io.PrintWriter;
public class VXMLUtils {
public static void printHeader(PrintWriter out) throws IOException {
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.println("<vxml version=\"2.1\">");
}
public static void printFooter(PrintWriter out) throws IOException {
out.println("</vxml>");
}
}
|
The advantages here should be fairly obvious. First, you can now move any function that you use across your VXML into the new VXMLUtils class. That makes changing, say, the version of VXML you are using in the header a piece of cake. Second, you can use this utility class in all of your VoiceXML servlets. So now you're avoiding repeating information, and have centralized that information. A change to the VXML version, then, affects all your VXML output, and you never have to change your servlets' source files.
Add to that the ability to represent different VXML files with different classes, and you're really starting to build a flexible framework. For example, note in Listing 6 the use of MusicVXML, another new class. This class takes care of the VXML related to the music file (minus the common VXML now dealt with by VXMLUtils). Listing 7 shows this class; it's remarkably simple.
Listing 7. MusicVXML, handling output of the music VXML file
package com.ibm.vxml;
import java.io.IOException;
import java.io.PrintWriter;
public class MusicVXML {
public static void printMainMenu(PrintWriter out) throws IOException {
out.println(
" <link next=\"#Menu\">\n" +
" <grammar type=\"text/gsl\">[menu begin start (start over)]</grammar>\n" +
" </link>\n" +
"\n" +
" <form id=\"Menu\">\n" +
" <block>\n" +
" <prompt>Welcome to the Menu.</prompt>\n" +
" </block>\n" +
"\n" +
" <field name=\"TypeOfMusic\">\n" +
" <prompt>What is your favorite type of music?</prompt>\n" +
" <grammar type=\"text/gsl\">\n" +
" <![CDATA[[\n" +
" [blues] {<TypeOfMusic \"blues\">}\n" +
" [jazz swing] {<TypeOfMusic \"jazz\">}\n" +
" [rap urban (hip hop)] {<TypeOfMusic \"hip\">}\n" +
" [rock (rock and roll)] {<TypeOfMusic \"rock\">}\n" +
" ]]]>\n" +
" </grammar>\n" +
"\n" +
" <noinput>\n" +
" <prompt>I didn't get that. Can you try again?</prompt>\n" +
" <reprompt />\n" +
" </noinput>\n" +
" <nomatch>\n" +
" <prompt>Try another kind of music.</prompt>\n" +
" <reprompt />\n" +
" </nomatch>\n" +
" </field>\n" +
"\n" +
" <filled>\n" +
" <if cond=\"TypeOfMusic == 'blues'\">\n" +
" <goto next=\"#Blues\" />\n" +
" <elseif cond=\"TypeOfMusic == 'jazz'\" />\n" +
" <goto next=\"#Jazz\" />\n" +
" <elseif cond=\"TypeOfMusic == 'hip'\" />\n" +
" <goto next=\"#Hip\" />\n" +
" <elseif cond=\"TypeOfMusic == 'rock'\" />\n" +
" <goto next=\"#Rock\" />\n" +
" </if>\n" +
" </filled>\n" +
" </form>");
}
public static void printOptions(PrintWriter out) throws IOException {
out.println(
" <form id=\"Blues\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Robert Johnson. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Jazz\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Django Reinhardt. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Hip\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Sorry, I don't have a clue on this one. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>\n" +
"\n" +
" <form id=\"Rock\">\n" +
" <field name=\"ReturnToMain\">\n" +
" <prompt>\n" +
" Check out Eric Clapton. It doesn't get any better. For\n" +
" other ideas, say \"Menu\".\n" +
" </prompt>\n" +
" </field>\n" +
" </form>");
}
}
|
All you need to do now is compile these three files (the servlet and the two VXML output files), and you've got dynamically generated VXML. The beauty of this is that now one developer (or team) can handle the servlet programming; another can work with common VXML methods and utilities; and a third can work on the music VXML file. These groups only have to communicate the available method signatures (just as you'd publish a Java interface); beyond that, the development processes are completely independent of each other.
There's another, slightly less obvious advantage to this approach. Look back at Listing 5, and notice that the VXML output is comprised of output from both the VXMLUtils class and the MusicVXML class. This probably doesn't seem all that earth-shattering, until you begin to really consider its implications.
First, you're no longer limited by file boundaries. For example, a 1,000-line VXML file could be output by a servlet, or five 200-line VXML files could be output by a servlet, with both ending up represented to the client as a 1,000-line VXML output. In other words, extremely large and complex VXML output can be constructed from smaller files or components. The result is that it's easier to maintain these smaller, segregated code bases, but the smaller sections can easily be combined as needed for larger output.
Another advantage is that you can mix and match output sections. For example, if you have one section from MusicVXML that might be appropriate for use in a VXML file about the iTunes music store, you can simply include that portion of VXML by calling a method on MusicVXML. The output from the servlet is the same as if you had read all the VXML from a single file, but the maintenance costs are far lower, as you're reusing code and VXML. Even better, if you change the VXML in the music file, all servlets and applications using that class's methods are updated immediately. The result is not only maintainability, but also flexibility.
The server doesn't matter to the client
One thing you should keep in mind here is the difference between the code running on the server, and what a telephone or wireless client actually receives. From the server perspective, it makes quite a difference if you place your VXML in a static file that is accessed directly by a client, or a static file that is loaded and output by a servlet, or a servlet that generates VXML from scratch, or a PHP script, or a CGI program, or ... well, you get the idea. Each different type of VXML provider has different requirements for resources, memory, and so forth, and some may even require additional software to run (like a servlet engine). So all of these things have to be considered when you're making a decision about your VoiceXML delivery framework.
However, none of this actually matters to the client. As soon as a servlet outputs VXML -- whether that VXML is loaded from a file or created in-memory from scratch -- the servlet (or what have you) is finished with the process. A telephone client or wireless device, in fact, has no knowledge about how it got a particular piece of VXML; it just cares that it actually got the VXML. So, from the user perspective, you can use whatever approach you want.
If you think about this, it offers you quite an advantage. If it's more convenient to use servlets -- and the resource cost on your server isn't too high -- then you can use servlets. You don't have to worry about this particular client or that particular device supporting the Java platform, as no Java code is required on the client end. The servlet outputs VXML, and then gets out of the way. The same is true if you would prefer to stick with "plain old static files"; no wireless users are going to snicker at the lack of programming horsepower serving their application. The bottom line is that you can use whatever approach is the most flexible. For simple applications, that probably means static files. And for cases where you do want more dynamic interaction, then servlets are a great choice -- and no client software is needed to make things work.
Multipage or multisection applications?
You've seen both multipage and multisection applications in this article. In terms of functions, you should be able to program each type of application to perform the same steps, and users really won't be able to tell the difference between a multipage application and multisection application. That suggests that the choice between multipage and multisection is arbitrary, and either works well in any given situation.
Nothing could be further from the truth, though, and as much thought should be put into the application's architecture as into the application's functions. Choosing the right architecture (multipage or multisection) can have huge effects on your users, even though the functions would be the same.
Advantages of multisection (single-page) applications
First, it should be stated that the choice between a single-page or multipage has almost no effect on telephony users. The difference between a multisection and multipage application is largely invisible to someone on a phone, as network bandwidth and file size have no real bearing on a telephone connection.
However, VoiceXML applications are being accessed as often by wireless devices as by telephones -- and in some cases, more often. It's here that the two platforms produce different effects on the user. A wireless device often has a very small amount of bandwidth over which to download files, applications, or resources. Downloading a lengthy VXML file -- and the VXML files that form multisection applications are usually quite lengthy -- would seem, then, to be a bad idea. However, it's common to have a lengthy pause when first accessing a new application, and users are accustomed to this delay. So there's little penalty for the initial download of a multipage application, at least as perceived by the user.
However, after the application has been accessed, users' patience shrinks considerably. When users click a button or access a feature, they don't like to wait around. For this reason, a multisection application often excels on mobile or wireless devices. Because the links within a multisection application refer to other parts of the same file -- which has already been downloaded -- the effect is that the application appears quick and responsive. You can lump together similar functions, and only refer to a new VXML file when a new function is requested. In cases where users are trying to access a completely different part of an application, they are more likely to tolerate another wait, much as they did when they first accessed your application.
So if you want to really optimize content for wireless devices, consider the multisection application. Users often report that these types of applications feel quicker, and they require little extra work.
Advantages of multipage applications
On the opposite side of the coin is the multipage application, where a VXML file is used for each option, or sub-option, in an application. Many of the same considerations mentioned above apply here: telephony customers rarely are affected by the type of application, while wireless clients are.
After the lengthy list of reasons that a multisection application is great for mobile devices, it might seem as if there would never be a good time to use a multipage application. However, this isn't the case. Just as mobile devices have small amounts of bandwidth to download files, they often have costs associated with downloads; so a smaller file would cost less to download than a larger one. Even with the unlimited bandwidth plans available, many non-business users are still paying by the minute or by the kilobyte. In these cases, a multipage application, with lots of smaller files, allows users to only download and pay for what they really want to use.
Additionally, lumping together lots of information in one VXML file is only effective if users access most of that information. If a VXML file has 20 sections, but typical usage shows that users only access 3 of those sections, the remaining 17 are a waste of time and bandwidth for that typical user. By using a multipage application, this concern is removed, as users only download what they want; each feature is in a separate VXML file.
It's probably no surprise that the "right" solution is to use both multipage and multisection applications, depending on the situation. Before you can do that, though, you need to take the critical first step of really analyzing and understanding your target user base. Are your users typically employing everything your application has to offer? Or do the majority of them go straight to one particular function? You need to have this information before you're ready to make any decisions.
After you understand typical usage patterns, you need to group common functions, and then break those groups into sections based on use. In other words, if the 10 pages that make up the main news portion of a site are almost always accessed as a group -- that is, if users generally don't read just one story, but read all 10 pages -- then consider putting all 10 pages into one multipage VXML file. Users will need to download more information at once, but they're going to access all of that information in most cases. So you're making the most of their time and bandwidth, and switching between stories will be quick and seamless.
On the other hand, if you find that users rarely click the "Help" link of your online store, you should place any help files in a separate application, rather than bundling them as a section of your store pages. Users that click "Help" experience a pause as the help VXML is downloaded, but the larger group of users who don't click the "Help" link won't pay the download and time cost for information they rarely use.
As you can see, all of this depends on really understanding your user base. Get an idea of how your application is to be used, and then you can make good decisions about how to structure your application. And remember, this all refers to the wireless side of your VoiceXML application; the telephony side is largely independent of the multipage/multisection discussion.
If you've followed along with the examples in this article, and have a couple of multipage and multisection VoiceXML applications running -- all powered by Java servlets -- then you've come a long way. Remember, it was just in the previous article in this series that you were getting your first servlet-based application running, and now you have the tools to build complex applications that jump between sections of a VXML file, as well from file to file.
More importantly, you should understand that there are times when it's best to output one large VXML file, and other times when it's better to output several smaller files. By making good decisions about how you break up your application, you can ensure that wireless devices accessing your applications function just as smoothly as telephony customers. You simply cannot spend too much time ensuring that your application is accessible to as many people, and by as many different types of devices, as possible. Whether you're after sales revenue, ad revenue, mindshare, public awareness, or just popularity, the more people and devices that can access your application the better.
In the next article in this series, you'll add another tool to your bag of tricks and techniques: JavaServer Pages (JSP) technology. It's fairly easy to get a JSP page to output XML, and VXML is just one more flavor of XML. In many cases, you don't need the processing capabilities of a servlet: in many cases, JSPs can provide you with dynamic programming abilities and spare you the overhead of writing servlet code. Be sure to come back next month for more on servlets, JSPs, and dynamic VoiceXML applications.
| Description | Name | Size | Download method |
|---|---|---|---|
| Code samples from the listings in this article. | wi-voicexml2.zip | 8KB | HTTP |
Information about download methods
Learn
- "Create VoiceXML pages within a Java Web developer framework" (developerWorks, January 2006): Read the first article in this series.
- "Deep into VoiceXML" (developerWorks, October 2002): This developerWorks tutorial helps you brush up on your VoiceXML skills if you're rusty, or new to VoiceXML or VXML.
- Voxeo: If you're confused about the difference between CallXML, CCXML, and VoiceXML, check out this great resource.
- Voice Browser activity page: The definitive source for specifications is the W3C's voice browser activity page, which has links to specs, FAQs, tools, and helpful articles.
-
VoiceXML 2.1 candidate recommendation status: VoiceXML 2.1 is expected to be approved any day now.
- Java and XML
(O'Reilly Media, Inc.): My own book, which has quite a bit of material on XHTML, serving XML on the Web, and serving content to multiple types of devices.
- XML in a Nutshell
(O'Reilly Media, Inc.): A great all-in-one XML resource, and has a chapter devoted to XML on the Web.
Get products and technologies
-
Voxeo.com: Sign up for great VoiceXML tools and utilize a great source of VoiceXML information.
-
Voxeo Community Tools page: This site is a good starting point for finding VoiceXML-related add-ons and utilities.

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 technology 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. His most recent book, Java 5.0 Tiger: A Developer's Notebook, is 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)





