Chapter 6

Document Sample
Chapter 6 Powered By Docstoc
					  Chapter 6

Multimedia content
  wml file for phone (for a servlet to
  find the location for an area code)
<?xml version="1.0"?>

<!DOCTYPE wml PUBLIC
 "-//WAPFORUM//DTD WML 1.1//EN"
 "http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
 <card id="AreaCode" title="Enter an Area Code">
  <do type="accept" label="Enter">
   <go href="servlet/AreaCode?code=$(code)"/>
  </do>
  <p>
  Enter an Area Code: <input type="text" name="code"/>
  </p>
 </card>
</wml>
          I used an html form




<FORM Method=GET
  Action="http://localhost:8080/servlet/AreaCode">
input area code <input type=text
  name="code"><p>
<input type =submit>
</form>
    It “sends” an xml (wml) doc
• <?xml version="1.0"?>
• <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML
  1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
• <wml>
• <card id="Code" title="Code">
• <p>
• Area code '607'<br/>
• is New York.<br/>
• </p>
• </card>
• </wml>
                            AreaCode
public class AreaCode extends HttpServlet {

 Properties lookup = new Properties();

 public void init() {
   // Transfer raw data from below into a fast-lookup Properties list
   for (int i = 0; i < data.length; i++) {
     Object[] record = data[i];
     String state = (String) record[0];
     int[] codes = (int[]) record[1];
     for (int j = 0; j < codes.length; j++) {
       lookup.put(String.valueOf(codes[j]), state);
     }
   }
 }
                                      AreaCode
public void doGet(HttpServletRequest req, HttpServletResponse res)
                      throws ServletException, IOException {
  res.setContentType("text/vnd.wap.wml");
  PrintWriter out = res.getWriter();
  String msg = null;
  String code = req.getParameter("code");
  String region = null;
  if (code != null) {
    region = lookup.getProperty(code); }
  out.println("<?xml version=\"1.0\"?>");
  out.println("<!DOCTYPE wml PUBLIC " +
           "\"-//WAPFORUM//DTD WML 1.1//EN\" " +
           "\"http://www.wapforum.org/DTD/wml_1.1.xml\">");

  out.println("<wml>");
  out.println("<card id=\"Code\" title=\"Code\">");
  out.println(" <p>");
  out.println(" Area code '" + code + "'<br/>");
  if (region != null) {
    out.println(" is " + region + ".<br/>"); }
  else {
    out.println(" is not valid.<br/>"); }
  out.println(" </p>");
  out.println("</card>");
  out.println("</wml>"); }
          AreaCode –just part of object[][]array
// Raw area code data for each region
  private Object[][] data = new Object[][] {
   { "Toll Free", new int[] { 800, 855, 866, 877, 888 } },
   { "Alabama", new int[] { 205, 256, 334 } },
   { "Alaska", new int[] { 907 } },
   { "Alberta", new int[] { 403, 780 } },
   { "Arizona", new int[] { 480, 520, 602, 623 } },
   { "Arkansas", new int[] { 501, 870 } },
   { "British Columbia", new int[] { 250, 604 } },
   { "California", new int[] { 209, 213, 310, 323, 369, 408, 415, 424, 510,
     530, 559, 562, 619, 626, 627, 650, 661, 707, 714, 760, 805, 818, 831,
     858, 909, 916, 925, 949 } },
   { "Colorado", new int[] { 303, 719, 720, 970 } },
   { "Connecticut", new int[] { 203, 475, 860, 959 } },
   { "Deleware", new int[] { 302 } },
   { "District of Columbia", new int[] { 202 } },
   { "Florida", new int[] { 305, 321, 352, 407, 561, 727, 786, 813, 850, 863,
     904, 941, 954 } },
   { "Georgia", new int[] { 229, 404, 478, 678, 706, 770, 912 } },
   { "Hawaii", new int[] { 808 } },
   { "Idaho", new int[] { 208 } },
   { "Illinois", new int[] { 217, 224, 309, 312, 618, 630, 708, 773, 815,
     847 } },
   { "Indiana", new int[] { 219, 317, 765, 812 } },
   { "Iowa", new int[] { 319, 515, 712 } },
   { "Kansas", new int[] { 316, 785, 913 } },
   { "Kentucky", new int[] { 270, 502, 606, 859 } },
   //lots more
                AreaCode
• Does not work in servletserver, but did
  work fine in Tomcat
• Properties class is part of the API
• I also created a similar application in java
  which worked fine.
      Using graphics in servlets
• For this servlet you’ll need 3 classes from Acme. You
   can find them yourself by searching.
• I will put the java files in our class directory
   (higgindm/internet programming) They are at
http://employees.oneonta.edu/Higgindm/internet
   programming/java/IntHashtable.java
(etc)
• The classes are
   – IntHashtable
   – ImageEncoder
   – GifEncoder
• Pay attention to the directory structure. These will need
  to be in special packages
          Using graphics in servlets
classes



             Acme



                       JPM



                                   Encoders



                                               GifEncoder



                                              ImageEncoder



                    IntHashtable
            Other sources
• There are other encoders available,
  including some from SUN.
• Directories
HelloWorld in Graphics
                           HelloWorld in Graphics
import java.io.*;
import java.awt.*;
import javax.servlet.*;
import javax.servlet.http.*;
import Acme.JPM.Encoders.GifEncoder;
public class HelloWorldGraphics extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse res)
                       throws ServletException, IOException {
  ServletOutputStream out = res.getOutputStream(); // binary output!
  Frame frame = null;
  Graphics g = null;
  try {
    // Create an unshown frame
    frame = new Frame();
    frame.addNotify();
    // Get a graphics region, using the Frame
    Image image = frame.createImage(400, 60);
    g = image.getGraphics();
    // Draw "Hello World!" to the off-screen graphics context
    g.setFont(new Font("Serif", Font.ITALIC, 48));
    g.drawString("Hello World!", 10, 50);
    // Encode the off-screen image into a GIF and send it to the client
    res.setContentType("image/gif");
    GifEncoder encoder = new GifEncoder(image, out);
    encoder.encode(); }
  finally {    // Clean up resources
    if (g != null) g.dispose();
    if (frame != null) frame.removeNotify(); } }}
DeColorize
                DeColorize
• This used 3 classes from ACME plus the
  GrayscaleFilter from text chapter 6. (as above:
  ImageEncoder, GifEncoder, IntHashtable)
• See previous slide for ACME, here’s a link for
  GifEncoder:
  http://www.acme.com/java/software/Acme.JPM.
  Encoders.GifEncoder.html
• If you are compiling in your java\bin directory,
  remember, as with text code classes, you’ll need
  to drop the package structure into webapps
  classes directory of tomcat
A page on the ACME site
                                   DeColorize
import com.oreilly.servlet.ServletUtils;
import Acme.JPM.Encoders.*;
public class DeColorize extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse res)
                    throws ServletException, IOException {
  res.setContentType("image/gif");
  ServletOutputStream out = res.getOutputStream();

  // Get the image location from the path info
  URL source = ServletUtils.getResource(getServletContext(),
                           req.getPathInfo());
  if (source == null) {
    res.sendError(res.SC_NOT_FOUND,
         "Extra path information must point to an image");
    return;
  }
  // Construct an unshown frame
  // No addNotify() because its peer isn't needed
  Frame frame = new Frame();
                                           DeColorize
// Load the image
    Image image = Toolkit.getDefaultToolkit().getImage(source);
    MediaTracker mt = new MediaTracker(frame);
    mt.addImage(image, 0);
    try {
      mt.waitForAll();
    }
    catch (InterruptedException e) {
      res.sendError(res.SC_INTERNAL_SERVER_ERROR,
            "Interrupted while loading image: " +
            ServletUtils.getStackTraceAsString(e));
      return;
    }
    // Get the size of the image
    int width = image.getWidth(frame);
    int height = image.getHeight(frame);
    // Make sure we are reading valid image data
    if (width <= 0 || height <= 0) {
      res.sendError(res.SC_NOT_FOUND,
            "Extra path information must point to a valid image");
      return;
    }
    // Create an image to match, run through a filter
    Image filtered = frame.createImage(
      new FilteredImageSource(image.getSource(),
                       new GrayscaleImageFilter()));
    // Encode and return the filtered image
    GifEncoder encoder = new GifEncoder(filtered, out);
    encoder.encode(); }}
          Caching images
• Hunter gives tips for caching the
  decolorized images in a hashtable.
• If a request comes in for a new image we
  go ahead and decolorize, if the image is
  already there, we send it to the user.
         Cache DeColorize: modify
               DeColorize
• Add a Hashtable:
Hashtable gifs=new Hashtable();
• Create a byte array outputstream:
ByteArrayOutputStream baos= new ByteArrayOutputStream(1024);
• After checking for null source, check if already saved this image:
if(gifs.containsKey(source)){
          baos=(ByteArrayOutputStream)gifs.get(source);
          baos.writeTo(out);
          return;}
• Otherwise, encode it to the Hashtable and also write to client
GifEncoder encoder = new GifEncoder(filtered, baos);
  encoder.encode();
  gifs.put(source,baos);
  baos.writeTo(out);
}
Merlin, for example…
          Cache decolorizer
• Remember, as with our view resources
  examples:
• Unless you write code to do
  upcase/lowcase on the pathinfo, java IS
  case sensitive and you may not get a
  match for a file merlin.gif if the file is
  merlin.GIF
 Like view resource…but compress
             if possible
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.oreilly.servlet.ServletUtils;
public class ViewResourceCompress extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse res)
                      throws ServletException, IOException {
  OutputStream out = null;
  // Select the appropriate content encoding based on the
  // client's Accept-Encoding header. Choose GZIP if the header
  // includes "gzip". Choose ZIP if the header includes "compress".
  // Choose no compression otherwise. Make sure the Content-Encoding
  // uses the "x-" prefix if and only if the Accept-Encoding does.
  String encodings = req.getHeader("Accept-Encoding");
  if (encodings != null && encodings.indexOf("gzip") != -1) {
    // Go with GZIP
    if (encodings.indexOf("x-gzip") != -1) {
      res.setHeader("Content-Encoding", "x-gzip");
    }
    else {
      res.setHeader("Content-Encoding", "gzip");
    }
    out = new GZIPOutputStream(res.getOutputStream());
  }
           Compress resources servlet
else if (encodings != null && encodings.indexOf("compress") != -1) {
     // Go with ZIP
     if (encodings.indexOf("x-compress") != -1) {
       res.setHeader("Content-Encoding", "x-compress");
     }
     else {
       res.setHeader("Content-Encoding", "compress");
     }
     out = new ZipOutputStream(res.getOutputStream());
     ((ZipOutputStream)out).putNextEntry(new ZipEntry("dummy name"));
   }
   else {
     // No compression
     out = res.getOutputStream();
   }
   res.setHeader("Vary", "Accept-Encoding");
   // Get the resource to view
   URL url = null;
   try {
     url = ServletUtils.getResource(getServletContext(), req.getPathInfo());
   }
   catch (IOException e) {
     res.sendError(
       res.SC_NOT_FOUND,
       "Extra path info must point to a valid resource to view: " +
       e.getMessage());
   }
             Compress resources servlet
        // Connect to the resource
        URLConnection con = url.openConnection();
        con.connect();

        // Get and set the type of the resource
        String contentType = con.getContentType();
        res.setContentType(contentType);

        // Return the resource
        try {
          ServletUtils.returnURL(url, out);
        }
        catch (IOException e) {
          res.sendError(res.SC_INTERNAL_SERVER_ERROR,
               "Problem sending resource: " + e.getMessage());
        }

        // Write the compression trailer and close the output stream
        out.close();
    }
}
              ServerPush
• Server Push is the server-side version of
  the client “request- refresh” servlets we
  saw.
• It uses a com/oreilly/class
  MultipartResponse to package a series of
  web pages to be “pushed” to the client.
• IE does not support server push but it runs
  ok in current version (7?) of Netscape.
      sending country names and flags
ServletOutputStream out = res.getOutputStream(); // some binary
   output
  // Prepare a multipart response
  MultipartResponse multi = new MultipartResponse(res);

  // send a name, then a country's flag
  for (int i = 0; i < country.length; i++) {//for

  multi.startResponse("text/html");
  out.println("<html><title>"+country[i]+"</title></html>");
  try { Thread.sleep(1000); } catch (InterruptedException e) { }
  multi.endResponse();
  multi.startResponse("image/gif");
   try {ServletUtils.returnFile(req.getRealPath(flags[i]), out); }
   catch (FileNotFoundException e) {throw new
  ServletException("Could not find file: " + e.getMessage());}
  try { Thread.sleep(1000); } catch (InterruptedException e) { }
                 images
• Tomcat will find images in your context if
  you have an images directory on the same
  level as your web-inf directory.
My first “flag” was simpsons

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:10
posted:5/7/2011
language:English
pages:29