home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book Home Java Servlet Programming Search this book

Chapter 13. Odds and Ends

Every house has a junk drawer--a drawer loaded to the brim with odds and ends that don't exactly fit into any organized drawer and yet can't be thrown away because when they're needed they're really needed. This chapter is like that drawer. It holds a whole slew of useful servlet examples and tips that don't really fit anywhere else. Included are servlets that parse parameters, send email, execute programs, use regular expression engines, use native methods, and act as RMI clients. There's also a demonstration of basic debugging techniques, along with some suggestions for servlet performance tuning.

13.1. Parsing Parameters

If you've tried your hand at writing your own servlets as you've read through this book, you've probably noticed how awkward it can be to get and parse request parameters, especially when the parameters have to be converted to some non-String format. For example, let's assume you want to fetch the count parameter and get its value as an int. Furthermore, let's assume you want to handle error conditions by calling handleNoCount() if count isn't given and handleMalformedCount() if count cannot be parsed as an integer. To do this using the standard Servlet API requires the following code:

int count;

String param = req.getParameter("count");
if (param == null || param.length() == 0) {
  handleNoCount();
}
else {
  try {
    count = Integer.parseInt(param);
  }
  catch (NumberFormatException e) {
    handleMalformedCount();
  }
}

Does this look like any code you've written? It's not very pretty, is it? A better solution is to hand off the responsibility for getting and parsing parameters to a utility class. The com.oreilly.servlet.ParameterParser class is just such a class. By using ParameterParser, we can rewrite the previous code to be more elegant:

int count;

ParameterParser parser = new ParameterParser(req);
try {
  count = parser.getIntParameter("count");
}
catch (NumberFormatException e) {
  handleMalformedCount();
}
catch (ParameterNotFoundException e) {
  handleNoCount();
}

The parameter parser's getIntParameter() method returns the specified parameter's value as an int. It throws a NumberFormatException if the parameter cannot be converted to an int and a ParameterNotFoundException if the parameter isn't part of the request. It also throws ParameterNotFoundException if the parameter had a value of the empty string. This often happens with form submissions for text fields when nothing is entered, something that for all intents and purposes should be treated the same as a missing parameter.

If it's enough that a servlet use a default value if there's a problem with a parameter, as is often the case, the code can be simplified even further:

ParameterParser parser = new ParameterParser(req);
int count = parser.getIntParameter("count", 0);

This second version of getIntParameter() takes a default value of 0 that is returned in lieu of throwing an exception.

13.1.1. ParameterParser Code

The ParameterParser class contains more than a dozen methods that return request parameters--two for each of Java's native types. It also has two getStringParameter() methods in case you want to get the parameter in its raw String format. The code for ParameterParser is provided in Example 13-1; ParameterNotFoundException is in Example 13-2.

Example 13-1. The ParameterParser class

package com.oreilly.servlet;

import java.io.*;
import javax.servlet.*;

public class ParameterParser {

  private ServletRequest req;

  public ParameterParser(ServletRequest req) {
    this.req = req;
  }

  public String getStringParameter(String name)
      throws ParameterNotFoundException {
    // Use getParameterValues() to avoid the once-deprecated getParameter()
    String[] values = req.getParameterValues(name);
    if (values == null)
      throw new ParameterNotFoundException(name + " not found");
    else if (values[0].length() == 0)
      throw new ParameterNotFoundException(name + " was empty");
    else
      return values[0];  // ignore multiple field values
  }

  public String getStringParameter(String name, String def) {
    try { return getStringParameter(name); }
    catch (Exception e) { return def; }
  }

  public boolean getBooleanParameter(String name)
      throws ParameterNotFoundException {
    return new Boolean(getStringParameter(name)).booleanValue();
  }

  public boolean getBooleanParameter(String name, boolean def) {
    try { return getBooleanParameter(name); }
    catch (Exception e) { return def; }
  }

  public byte getByteParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Byte.parseByte(getStringParameter(name));
  }

  public byte getByteParameter(String name, byte def) {
    try { return getByteParameter(name); }
    catch (Exception e) { return def; }
  }

  public char getCharParameter(String name)
      throws ParameterNotFoundException {
    String param = getStringParameter(name);
    if (param.length() == 0)  // shouldn't be possible
      throw new ParameterNotFoundException(name + " is empty string");
    else
      return (param.charAt(0));
  }

  public char getCharParameter(String name, char def) {
    try { return getCharParameter(name); }
    catch (Exception e) { return def; }
  }

  public double getDoubleParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return new Double(getStringParameter(name)).doubleValue();
  }

  public double getDoubleParameter(String name, double def) {
    try { return getDoubleParameter(name); }
    catch (Exception e) { return def; }
  }

  public float getFloatParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return new Float(getStringParameter(name)).floatValue();
  }

  public float getFloatParameter(String name, float def) {
    try { return getFloatParameter(name); }
    catch (Exception e) { return def; }
  }

  public int getIntParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Integer.parseInt(getStringParameter(name));
  }

  public int getIntParameter(String name, int def) {
    try { return getIntParameter(name); }
    catch (Exception e) { return def; }
  }

  public long getLongParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Long.parseLong(getStringParameter(name));
  }

  public long getLongParameter(String name, long def) {
    try { return getLongParameter(name); }
    catch (Exception e) { return def; }
  }

  public short getShortParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Short.parseShort(getStringParameter(name));
  }

  public short getShortParameter(String name, short def) {
    try { return getShortParameter(name); }
    catch (Exception e) { return def; }
  }
}

Example 13-2. The ParameterNotFoundException class

package com.oreilly.servlet;

public class ParameterNotFoundException extends Exception {

  public ParameterNotFoundException() {
    super();
  }

  public ParameterNotFoundException(String s) {
    super(s);
  }
}


Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.