Welcome!

Boris Minkin

Subscribe to Boris Minkin: eMailAlertsEmail Alerts
Get Boris Minkin via: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Java EE Journal, Apache Web Server Journal, XML Magazine, Java Developer Magazine

J2EE Journal: Article

XSLT Solution for Java EE Applications

Adding pervasive computing support to existing applications

Applying XSLT (eXtensible Stylesheet Language for Transformations) to XML documents can be done using the Java EE (formerly J2EE) Servlet filters model and Java Server Pages (JSP) technology. Servlet filters can be invoked before or after the invocation of a particular servlet or JSP, based on the incoming URL mapping, which could be specified as the central controller servlet in a framework such as Struts or a custom-developed one. The basic logical model is shown in Figure 1.

In Figure 1, a Struts framework is used in combination with Servlet filters technology. When a request comes from the client (Browser, PDA or Smart Phone), the controller servlet of the Struts framework gets called and in turn, invokes an appropriate action based on the mapping of the submitted URL, as defined in Struts configuration file (struts-config.xml). Inside the action, a particular Web controller logic is processed (such as parsing of parameters) and then a business logic bean is invoked (for example, EJB), which communicates with the database server and performs necessary database operations in the appropriate transactional scope. A response from the business bean then is encapsulated in the action response and is delivered to the client by the corresponding JSP.

In this case, the JSP would be coded in the XML form - meaning that the JSP file will not contain HTML as it usually does, but an XML markup instead. A reference to the proper XSLT style sheet would be dynamically generated, based on the MIME type of the incoming request (UserAgent header for most of the HTTP-based clients). Application of XSLT can be done using Servlet Filter technology, where the servlet or JSP response is modified after the processing by the servlet is completed. Modification of the servlet response would encompass the application of the appropriate XSLT style sheet using, for example, Java API for XML Processing (JAXP). This actually simplifies things, since no custom XML parser is required, and one can use standard J2SE technology to utilize all XML-based processing (such as DOM, SAX, and XSLT).

Listing 1 demonstrates the usage of JAXP API for processing and passing transformation to the HTTP Servlet response.

The xmlSource and styleSource variables in the Code Listing 1 have the StreamSource type, containing source of XML and XSLT stylesheets.

In Listing 1, several JAXP classes are used. First, TransformerFactory class follows the Factory design pattern to generate a new instance of XSLT transformers. The file name XSLT would be supplied as a parameter, while original XML source would come from the JSP response. CharArrayWriter is used to buffer the contents to be sent later on to the HttpServletResponse output stream.

Advantages and Disadvantages of This Approach
The advantages of using XSLT include:

  • The ability to better separate model, view and controller in the application.
  • An additional view tier (XSLT stylesheet) is introduced that is completely separate from any Java or logical processing and encourages developers to use optimal design strategies without mixing Java code with the view (something that commonly happens in the coding of regular JSP pages).
  • The JSP is device-independent: it contains just XML, or data which can be converted into any appropriate view for the particular device, be it Wireless Markup Language (WML), XHTML, regular HTML, etc.
The disadvantage of this approach is that we need an extra layer of processing which can introduce additional performance burden on the system. This is because the application of XSLT is generally a processor-intensive operation, and for large JSP pages, especially large style-sheets, performance degradation can result. One way to partially mitigate this problem is to allow the client to handle the application of XSLT. For instance, newer versions of the Internet Explorer browser such as 6.0 SP1 or later include an XSLT engine that's compliant with W3C standards, and can easily replace server based XSLT application. In the client XSLT processing model, the sever will pass XML and XSLT style sheets directly to the browser, and the browser will be responsible for actually applying the stylesheet to the XML data, unlike the server XSLT processing mechanism, when XSLT is applied to XML on the server and the result is passed to the client. However, this approach is limited due to the inability of other client devices to perform similar operations - it would be highly unlikely to expect PDA or Smart Phone to perform such an extensive operation as XSLT's transformation.

Another possibility is that developers experience difficulty debugging XSLT without the use of extra tools. Besides, XSLT is difficult to debug because it is not a complied language. Everything is happening at the runtime during execution of the XSLT application. Industrial-strength development environments, such as Microsoft Visual Studio and IBM WebSphere Studio Application Developer include powerful debuggers that help alleviate this issue.

Converting Existing J2EE Application to XSLT Approach
The following few steps will describe the conversion of the existing J2EE applications to use the XSLT approach to display content to multiple device types.

Environment Setup
We'll use DBTestSH application developed in the article entitled: "Bringing Together Eclipse, WTP, Struts, and Hibernate"(http://java.sys-con.com/read/216320.htm). We'll use the following tools and technologies:

The purpose of this exercise is to extend the existing application to use XSLT style sheets to convert our JSP pages (coded as XML documents) into the format appropriate for the particular agent type, e.g., Microsoft Mobile Explorer or Microsoft Internet Explorer.

In order to set up the environment, we need to do a few steps over those described in previous article http://java.sys-con.com/read/216320.htm. First, make a copy of the DBTestSH project (obtained from the previous article). Simply right-click on it and select "Copy." Then right-click again, select "Paste," and the simple screen shown in Figure 2 will be displayed by Web Tools.

After that, several important libraries need to be added under WEB-INF\lib. These are XSLT parser libraries. We'll use open-source Apache Xalan-J processor to do the job; it works quite well with Sun standard JAXP API. The following JARs have to be placed under WEB-INF\lib:

xalan.jar      - Xalan XSLT processor.
xercesImpl.jar      - implementation of Xerces XML parser.
xml-apis.jar      - XML APIs for JAXP compatibility.
serializer.jar      - XML serialization APIs.

We'll also create a new directory structure under Web Content for our XSLT style-sheets:

  • WebContent
    - stylesheets
  • ie: Will contain style sheets for Internet Explorer.
  • Wml: Will contain style sheets for Microsoft Mobile Explorer.
This can be easily done using the Eclipse "New Folder" wizard.

Servlet Filter Code and Job Description
The conversion job as shown in Figure 1 will be done by a Servlet Filter. Servlet Filters have been a standard part of Servlet API since version 2.3. They allow modifying HTTP response and can serve many different purposes, including enforcing security or access restrictions of the application, caching the application content, etc. In our example, however, we'll use servlet filters to process applications of the XSLT style sheet to the XML data passed from the JSP. My example has been partially borrowed from Sun Microsystems' reference to servlet filters implementation at http://java.sun.com/products/servlet/Filters.html, however, a few modifications were made to the code in Listing 2 in order to fit into our application. For instance, I've added the code to determine the content type based on the "user-agent" header (containing client information, such as browser type) and to determine the appropriate XSLT style sheet based on the provided request URI.

In Listing 2, we use a reference to the CharResponseWrapper class that is used to wrap HttpServletResponse, so its String contents can be easily retrieved when needed.

Listing 3 shows a simple wrapper for HttpServletResponse from a servlet.

Listing 2 has several important methods that were added to fit Sun's example into our application:

  • determineStylesheetNameFromRequest: Determines the style sheet name based on the request URI. Another way of doing this is by using XML file mapping, which looks like a more elegant approach, but for the purposes of simplicity, we have just hard-coded the mappings between URIs and corresponding XSLT stylesheets.
  • determineStylesheetPathFromRequest: We'll have a couple of directories under our Web Content root directory where XSLT stylesheets will be placed - each directory corresponds to the set of stylesheets for a particular browser type.
  • determineContentTypeFrom: We also need to determine the content type of the request. For the Internet Explorer, it would simply be "text/html". For a Wireless Access Protocol (WAP) browser, such as Microsoft Mobile Explorer, or PDA, or a smart phone capable of serving WML content, it would be "text/vnd.wap.wml". Other types can be added by simple modification of this method.
Now, that we covered auxiliary private methods of ApplyXSLTFilter.java, let's talk about how the method doFilter(ServletRequest, ServletResponse, FilterChain) works. Once the content type, the XSLT style sheet name and the path are determined by calling methods at the beginning of the filter processing, we set the response type to the content type determined and get the real OS path for the stylesheet using a handy method called getRealPath(String) of javax.servlet.ServletContext. Now, we have our style sheet source by reading a file using StreamSource class from JAXP.

In the next step, we obtain the response writer from HttpServletResponse, wrap it in CharResponseWrapper and pass control to doFilter(ServletRequest, ServletResponse, FilterChain), which executes the underlying Struts action and populates our response with data. Obtaining this data is easy if you use the same wrapper class, and we have our XML source - wrapped as StreamSource class from JAXP.

Finally, XSLT transformation will take place and write the transformed output to the HTTP response, displaying it to the appropriate device type.

Setting up the Servlet Filter in the Web Deployment Descriptor
A Java Web application actually knows that it has a servlet filter from the Web Deployment Descriptor: web.xml file, as shown in Listing 4.

This mapping specifies the name of the Servlet filter and its class. IT also defines the association with URI patterns that this filter will be invoked upon. Since we use Struts, *.do pattern will be associated with all the filter invocations. JSP pages can be invoked independently from Struts, so we also need to make sure that the JSP association with Servlet Filter is held on. For that purpose, one minor step needs to be done: index.html page should be renamed to index.jsp, so that our filter knows to handle it. Otherwise, we'd have to add a third mapping for *.html files.

Converting Our JSP Pages
As described at the beginning of this article, existing JSP pages will be split into JSP files producing XML and style sheets with XSLT content. All the scriplets, expressions, and other JSP artifacts will remain in JSP pages, but all the graphics, HTML content, JavaScript, and all the view artifacts will go to the appropriate XSLT style sheets. Listing 5 shows the example of such a conversion.

Now, we remove all the graphics from customer.jsp, all the view producing code (remember MVC?), keeping only the data in XML format, as shown in Listing 6.

As we can see from Listing 6, all the scriplets, expressions, jsp:useBean tags - all this is remaining in the JSP file, but all the view attributes are gone. Where? They go into XSLT stylesheets - one for each browser type - under the corresponding directory, as shown in Listing 7.

For those, who are not familiar with XSLT, it may be somewhat hard to understand the code in Listing 7. Basically, the entire HTML is wrapped into a sing XSLT template that is applied to the root of the XML document during transformation. "xsl:for-each" is a loop construct in XSLT that allows looping through a bunch of XML data - in our case customer data. At every step, it displays the corresponding customer data using "xsl:value-of select" construct that displays a particular attribute of the CUSTOMER element from our JSP/XML file (such as ID, first name, last name, etc.). Note the "xsl:output" element, which designates the content type as text/html.

Listing 8 is the style sheet for WML output.

When we invoke the Mobile Explorer Emulator, we should be able to see our customer list on a mobile phone screen, as shown in Figure 3.

Conclusion
In this article, I showed you how to convert a Java Web application to be used with multiple device types. It added an extra layer of processing, but at the same time increased application flexibility greatly by allowing supporting multiple independent views using the same back-end model, in the letter and spirit of Model-View-Controller paradigm. Using Eclipse and Web Tools simplifies this job even further, as they provide JSP editors, XML editors, and validators that allow one to make sure their XSLT and XML source is valid and will execute properly.

My wish list for Web Tools starts with a XSLT debugger that would allow debugging XSLT processing just like in Java. This would help tremendously in figuring out what's wrong with your XSLT code, but for now, we still have to rely mainly on the console messages.

More Stories By Boris Minkin

Boris Minkin is a Senior Technical Architect of a major financial corporation. He has more than 15 years of experience working in various areas of information technology and financial services. Boris is currently pursuing his Masters degree at Stevens Institute of Technology, New Jersey. His professional interests are in the Internet technology, service-oriented architecture, enterprise application architecture, multi-platform distributed applications, and relational database design. You can contact Boris at bm@panix.com.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.