servlet| Dynamic | control | graphics Writing Custom JSP Tags
Now that you understand how the WEB server handles JSP page requests, let's look at how to implement custom JSP tags. Note: JSP tags come from both standard libraries (such as Java Standard Template Library,jstl) and from libraries you write yourself (also known as custom tags). Typically, custom tags deal with specific problem areas. For the purposes of this article, we are dealing with how to manage images. Currently, Java 2 Extended Edition (ee) V1.2 and V1.3 use JSP specification V1.2. At the time of writing this article, Sun has released the JSP specification V2.0. This new specification does not make significant changes to the way that custom tags are implemented.
By taglib pseudo directives, you can import standard and custom tag libraries into JSP pages, as follows:
<%@ taglib uri= ' imagesizer.tld ' prefix= ' util '%>
This pseudo-directive specifies the location of the tag library descriptor file, where the IMAGESIZER.TLD is specified, and the prefix that is used in the page is specified, where util is specified. Use the tag along with its prefix and its name, as shown in the previous markup example:
<util:imagesizer src= "Http://www.163design.net/j/f/images/LazyDog.jpg"/>
The tag library descriptor tells the Web container which tags are available and how they work. Listing 1 shows an example of this. Files are used in XML format and are easy to read, and application development platforms such as IBM WebSphere Studio application Developer (Application Developer) can help you populate fields and validate files. The most important information is the tag element: it defines the name of the custom JSP tag and the Java class that implements the tag. It also shows any attributes and body content that the tag accepts.
Listing 1. Tag Library descriptor (Tag libraries descriptor,tld) excerpt
<taglib > <tlibversion> 1.0 </tlibversion> <jspversion> 1.1 </jspversion> <tag> <name>imagesizer</name> <tagclass>tags. imagesizertag</tagclass> <bodycontent>empty</bodycontent> <attribute> <name>src</name> <required>required</required> </attribute> < attribute> <name>alt</name> </attribute> <attribute> <name >quality</name> </attribute> </tag></taglib>
In this example, tag has three properties, where only the SRC attribute is required. The optional ALT attribute simulates the HTML img alt attribute. As an exercise, you can extend the JSP tag to include other optional IMG attributes. (There are about 12 of these properties.) Finally, the implementation provides an optional quality property so that the page writer can control the granularity and size of the resized image. The next step in the
writing custom JSP tags is the Java code that implements the markup. In this article, the tag Imagesizer is in tags. Implemented in the Java class Imagesizertag. Most Java EE custom tag support is located in the Javax.servlet.jsp.tagext package. The Imagesizer class inherits the standard TagSupport, which implements the tag without the principal. The descendant class of the TagSupport is Bodytagsupport, and it implements the token, with the body. These two categories of Dee to? The tag interface in which the doStartTag and Doendtag methods are invoked when the token is first read and the markup is read again after the WEB container has fully read the tag. The Imagesizer tag only implements the Doendtag, because it needs to work once all the property information is available.
in the TagSupport class, the PageContext class provides access to important information about JSP pages. For example, PageContext provides access to HttpRequest and HttpResponse objects. These objects are essential for reading form values and write responses. If you want to track the user's preferences and pass the form values from one page to another, the request also provides access to HttpSession. PageContext also provides access to ServletContext, which helps you find the path, name, and other information for the servlet. In the Imagesizer code (shown in Listing 2), there are many references to PageContext objects and their information. Figure 3 shows the relationship of these classes. Like any standard class diagram, a solid box represents a class, and a dashed box represents an interface. Represents inheritance with a line from a derived class or interface to its parent class or interface.
Listing 2. Imagesizertag Doendtag Implementation
Implement the tag once the complete tag has been read.public int Doendtag () throws Jspexception {//move request dat A to session. int outputsize = 0; String sizeval = Request.getparameter (Requestsizekey); if (sizeval!= null) {Session.setattribute (Requestsizekey, sizeval); Sizeval = (String) session.getattribute (Requestsizekey); if (sizeval!= null) {outputsize = Integer.parseint (sizeval); }//Get specified image locally. String ContextPath = Getcontextpath (request); Image image = Toolkit.getdefaulttoolkit (). GetImage (ContextPath + src); Imagesizer.waitforimage (image); int imagewidth = Image.getwidth (null); int imageheight = Image.getheight (null); if ((ImageWidth > 0) && (ImageHeight > 0)) {if (outputsize > 0) && (outputsize!= ima Gewidth)) {//Convert image to new size. Image outputimage = imagesizer.setsize (image, Outputsize,-1); Imagesizer.waitforimage (Outputimage); int outputwidth = Outputimage.getwidth (null); int outputheight = Outputimage.getheight (null); if (outputwidth > 0 && outputheight > 0) {//change image file name to Xxxx.size.jpg String ORIGINALSRC = src; int lastdot = Src.lastindexof ('. '); if (Lastdot >-1) {src = src.substring (0, Lastdot + 1); } setsrc (src + outputsize + ". jpg"); Write new size image to JPEG file. File File = new file (ContextPath + src); if (!file.exists ()) {out.println (""); FileOutputStream fos = new FileOutputStream (contextpath + src); Imagesizer.encodejpeg (FOS, outputimage, quality); Fos.close (); } imagewidth = Outputwidth; ImageHeight = Outputheight; }//If outputsize}//If image found//produce output tag. Out.print (" 0)) {out.print ("alt=\" + ALT + "\"); }//Add proper width, height. Out.print ("width=\" "+ imagewidth +" \ "height=\" "+ ImageHeight +" "); Out.println (">"); return eval_page;} Doendtag
Figure 3. The important Javax.servlet.jsp.tagext class
Listing 2 shows the Doendtag method for the Imagesizertag class. This is almost all the Java code needed to implement a custom JSP tag. It's a large piece of code, but it will help you understand it in order to understand it in a comprehensive way. First, any HTTP request parameters are saved in the HTTP session. The request comes with a property, such as a user preference for the image size, and saves it in a session so that it can follow the user from one page to another. To extend the functionality of this tag, you can extend it so that you can save user preferences in a cookie so that users can use their preferences the next time they visit the site.
The next step is to load the default image, which is used by the JSP page as the base diagram, and all other images are resized according to Kitu. Here, the Java.awt.Toolkit requests the image, which is loaded with imagesizer.waitforimage, and checks to see if it has been scaled properly. Mount pauses are required because the Java images are mounted asynchronously and are not always fully available when they are requested. In this example, the Imagesizer helper class performs the entire image processing operation, which is described further in the next section. If the width and height match, there is no need to resize the image, and the large chunk of the code is skipped, and HTML image tags are written using the image name and current size. This is all the work that JSP needs to do to simulate HTML image tagging.
If the user requests a new image size, the Imagesizer helper class resizes the image. Use file size to specify a new name for the image file, which is JPEG encoded and written to the file system. Next, the file that is just resized is used in the HTML image markup output. An alternate implementation of the tag might save disk space by saving the file in GIF or PNG format, or even providing an image through memory. However, listing 2 caches the resized files to disk for future use. As a result, it takes some server processing time to resize the first time, but then there is no need to process the image size when it is requested. The extension of the example might check the available disk space to help balance the limited file space with the instant information that you want to provide to the client.
resizing images
The previous section studied the steps for writing custom JSP tags. The Imagesizertag class automatically resizes the image to match the user's preferences. This section provides more detailed information about how you can use the Imagesizer class to resize and save the image as a JPEG file. Using the getScaledInstance method in the Java.awt.Image class, it is easy to resize the image in Java code. You can get a new resized image by using this method with the new width and high profile, or by providing a value of 1 for a parameter to maintain the aspect ratio. However, like any Java image, the image is not immediately available, so you must use Java.awt.MediaTracker to wait for the image to be fully loaded. The code is encapsulated by the Imagesizer Waitforimage method.
In this example, the hardest design point is deciding how to save the image. There are many options for coding and saving images in Java programming, and all options have different trade-offs.
Com.sun.image.codec. The package is available in the Java 2 SDK 1.2 and 1.3 implementations, but it is in a private package that may change in the future version of Java 2. The package is limited to JPEG encoding.
Java Image I/O API. In Java 2 SDK 1.4, the package is public and standard. However, the Java version of SDK 1.4 was not used when writing this article. The package provides good image manipulation features and encoding options.
Java Advanced Imaging API (Java Advanced Imaging API). This API is a standard extension, but it requires installation packages-your WEB administrator may not support this work.
Acme GIF Encoder (Acme GIF encoder). This software and many other Third-party image packs are useful, and you can incorporate them into the sample code, but there is a cost and maintainability problem. Unlike other options, the software is not free and does not fully support the GIF standard.
For listing 3, we use the COM.SUN.IMAGE.CODEC package because it is available in all Java EE 1.2 and 1.3 Web server containers, such as IBM WebSphere and Apache Tomcat. The encoders are simple and are 100% pure Java code, but they are in the Com.sun package. However, in the long run, the Java Image I/O package may be the direction of development. It is more powerful in terms of image conversion features and the ability to save in multiple file formats. Java Image I/O packages are not standard until Java 2 V1.4.
Now that you've decided which image-processing package to use, the code to save the JPEG file is fairly straightforward. Imagesizer's Encodejpeg method encapsulates this process:
Java.awt.image.BufferedImage object, an enhanced Java image descendant, created from an resized output image. Note A location is marked in the code where you can expand the example to add a logo, watermark, timestamp, or copyright information to the image.
After the Image is converted to BufferedImage, a JPEGImageEncoder object is created on the output stream. The output encoding quality ranges from 0.0 (worst) to 1.0 (best). The default value is 0.75, but 0.95 generates a larger file size with a more detailed image. As an extension of the example, you can consider the size of the image to determine the quality-a smaller image requires a higher quality setting, while a larger image requires a lower setting.
Encodes the image into the output stream and refreshes the stream to ensure that all information is displayed in the image file.
Listing 3. Imagesizer Encodejpeg Implementation
Encodes the given image at the given//quality to the output stream.public static void Encodejpeg (outputstream ou Tputstream, image outputimage, float outputquality) throws java.io.IOException { //Get a buffered Image fro M the image. BufferedImage bi = new BufferedImage (Outputwidth, Outputheight, Bufferedimage.type_int_rgb); Graphics2D Bicontext = bi.creategraphics (); Bicontext.drawimage (outputimage, 0, 0, null); Additional drawing code, such as //watermarks or logos can is placed here. Com.sun.image.codec.jpeg Package //is included in sun and IBM SDK 1.3. JPEGImageEncoder encoder = jpegcodec.createjpegencoder (outputstream); The default quality is 0.75. JPEGEncodeParam Jep = jpegcodec.getdefaultjpegencodeparam (BI); Jep.setquality (outputquality, true); Encoder.encode (BI, Jep); Outputstream.flush ();} Encodeimage
That is all that is needed to resize the image and save the image.
Package and deploy to WebSphere or Tomcat
This section explains how to package Imagesizer JSP tags and deploy them to application Server V4.0 or Apache Tomcat V4.0. Figure 4 shows the grab screen of the application Developer. The Navigator pane (windowpane) in the upper-left column shows the directory structure of the WEB application and how you must package custom JSP tags based on the Java EE specification. Because of the requirements of the Java EE specification, the directory structure is public for all WEB applications. Once this structure is archived, it becomes a Web archive (WAR) file and can be easily routed to WebSphere, Tomcat, or any other compatible Web container. A good development environment, such as application Developer, helps developers follow these specifications and generate valid applications.
Figure 4. Packaging in the WebSphere Studio application Developer Imagesizer
Under the Imagesizer project, there is a source code directory where the developer can choose whether to include the directory in the final war file. The WebApplication directory contains the actual program code. The sample project contains a test JSP page named Pickasize.jsp and a huge test image called Lazydog.jpg. Typically, the library version of the Imagesizer custom tag does not contain these. The implementation of the tag is located in the Web-inf directory. Java classes are all in web-inf/classes and the tag library descriptor (Tag library descriptor) file is located in Web-inf/tlds. These are standard directory layouts for all WEB applications. Other files in the tree Help set server options but are not required by the WAR file. Use the application Developer or the Java SDK to create the WAR file for the application.
To deploy a Web application on a Web application server (such as Tomcat), place the file in the Root/webapps directory and have the server expand the WAR file into a directory structure. For application Server, you can use the Web Application Wizard in Administrators Console to install the application. Once deployed, you can run the JSP page by accessing http://yourhostname:port/ImageSizer/PickASize.jsp.
Conclusion
Now you have created a JSP custom tag that automatically manages image scaling. Custom tags save you the task of resizing the image, and also enable users to specify their own preferences when they visit your site. You can easily extend the sample markup to perform various image operations: the copyright text, the timestamp, the logo, or the watermark. You can experiment with code by deploying code to Application Server or Apache Tomcat, and writing some image-based JSP pages or using a given example. Hopefully this article provides you with the "Take Out" JSP tag, as well as the code that allows you to further extend the functionality to suit your needs. Wish you a happy look at the picture!