chapter 6 multimedia content. wml file for phone (for a servlet to find the location for an area...

29
Chapter 6 Multimedia content

Post on 21-Dec-2015

214 views

Category:

Documents


1 download

TRANSCRIPT

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>

AreaCodepublic 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); } } }

AreaCodepublic 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 servletsclasses

Acme

JPM

IntHashtable

Encoders

GifEncoder

ImageEncoder

Other sources

• There are other encoders available, including some from SUN.

• Directories

HelloWorld in Graphics

HelloWorld in Graphicsimport 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

DeColorizeimport 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 servletelse 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 flagsServletOutputStream 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