Integrating XML and Java to Build Server Side ArcIMS Applications

Nianwei Liu


Abstract
ArcXML is the protocol for communication between different components of ArcIMS software. This paper focuses on how to build server-side ArcIMS application using XML on Java platform. The paper first discusses some architectural considerations, and outlines the basic components and work flow of a Java server-side solution. Several approaches are discussed in the following sections in detail, including: 1) using Java API for XML Parsing(JAXP), 2) using a specific W3C Document Object Model(DOM) implementation, 3) using Simple DOM for ArcXML (AxlDOM), and 4) using a non DOM based, primitive data type model: Java Objects for ArcXML(AxlObjects) combined with Simple API for XML Parsing (SAX) . Finally, the design and implementation of a comprehensive JSP solution is presented.


1. Introduction

ArcIMS is the latest Internet Mapping Software from Esri, providing a powerful framework for distributing spatial related information on the Internet. It comes with a rich set of "out of box" solutions that enable a web site to be built very quickly, and provides different flavors of customizing tools. Some of these tools are client-side based such as HTML viewer and Java Viewer, the others are server-based such as ActiveX connector and Cold fusion connector. In addition to those solutions, there have been interests on solutions that are server based, light-weighted and platform independent. Addtional server side Java support is introduced in ArcIMS3.1 via AppServerLink, the developer can communicate with application server via ArcXML string. However, the AppServerLink does not provide tools to process ArcXML in a convenient way. This paper will discuss some of the ideas and approaches for such solutions.

2. Architecture Selection and General Considerations

Before we start an application development, we need to to make a choice about what kind of architecture to adapt. We choose a server side, Java based and XML embedded solution.

Why Server-side? Processing ArcXML request/response at server side instead of client side offers many advantages:

Why Java? Java solution is cross-platform. Although ActiveX connector offers a flexible server-side solution, it only works on Windows platform. The portability of java solutions makes the development a lot faster, and the developer do not have to rewrite the code if the application is transferred to a UNIX or LINUX system.

Why XML? ArcXML provides an open protocol for data exchange between different components of the ArcIMS products. This open architecture gives the ArcIMS developers much more power than any previous IMS products from Esri. The fundamental task for an ArcIMS application is to generate and process the ArcXML request/response. The out-of-box server-side solutions provided by ArcIMS handle the XML for the programmers in the background by translating ArcXML to an object model((ActiveX connector) or another set of tags(Cold Fusion connector). One major drawback of these method is, it is very difficult to write customized functions, if these functions are not already deployed in the object model. By handling ArcXML directly, the developers can customize ArcIMS applications based on the ArcXML specification, take full advantage of the open architecture of ArcIMS.

3. Implementing an Object Model for ArcXML.

3.1 Where to plug-in the XML component?

The ArcIMS middleware consists of the ArcIMS Application Server and Connectors. The Connectors receive requests passed by web server, then pass the requests as ArcXML to application server, the application server redirect the request to one of the ArcIMS virtual servers (image server, geocode server, etc). The responses are sent back in the reverse order. The servlet connectors basically just pass the requests/responses, while ActiveX Connector and Cold Fusion Connector actually produce and parse the ArcXML.

Figure 1: ArcIMS connectors

The server side XML handler can be inserted in front of Servlet Connector. In this case, the browsers only need to send regular HTTP requests, and another set of objects can translate the requests into ArcXML, just like ActiveX XML library and Cold Fusion XML library do. Alternatively, a customized Connector can and send ArcXML directly to an application server.

Figure 2: Server side Java XML objects

After ArcXML request is generated, it needs to be sent to Application Server. The connectors talk with application server via TCP/IP. The protocol is proprietary and is not publicly available. In ArcIMS3.0, the request can be send to Servlet connector, the overhead being another trip via web server. In ArcIMS3.1, the request can be sent to AppServerLink.

3.2 How to use XML in ArcIMS applications.

Following are basic approaches to customize ArcIMS application in a Java Server context:

There are two basic public domain APIs for XML processing: Simple API for XML Parsing(SAX) and Document Object Model(DOM). DOM is a set of interfaces defined by the World Wide Web Consortium(W3C) DOM Working Group(http://www.w3c.org). It describes facilities for a programmatic representation of a parsed XML (or HTML) document. A Document Object Model is in a tree structure, where each node contains one of the components from an XML structure. Two most common types of nodes are Element nodes and text nodes. In ArcXML, text node is rarely used (only for ERROR and COORDS). Using DOM functions allows programmers to create nodes, remove nodes, change their contents, and traverse the node hierarchy.

The basic flow for a typical request/response is:

Figure 3: Document Object Model handling

For example, in a JSP frame work, a typical request can be sent from browser either through a HTML form, or simply a URL with parameters such as http://host/map.jsp?command=zoomIn. The web server will first match the URL pattern, then forward the request to the JSP engine. The compiled JSP servlet may check if there is a session object and construct one if not. Next the JSP servlet will exam the request parameters and construct a Document based on the request and the session object. The construction process is generally done by a Java class which use the DOM objects. This class is responsible for implementing mapping functions through XML manipulation. After the Document object is constructed, the request Document will be sent to an OutputStream. The other end of the stream is the application server. After the ArcIMS Spatial Servers finishes the work, the response will be sent back to an InputStream, and an XML parser, generally a DOM parser, will parse this stream and construct a response Document. The servlet then will traverse the document, retrieve the information, and write HTML back to the browser. The following section discusses in detail how to apply different techniques in the work flow.

3.2.1 Java API for XML Parsing

Java API for XML Parsing is a platform API for XML processing. The JAXP1.1 specification was released in March, 2001. The specification provides basic support for parsing and manipulating XML documents through a standardized set of Java Platform APIs.

For example, assume there is a HTTP request for a "zoom in", the servlet will retrieve the stored session object, get its previous extend and calculate the new extent, and then be ready to refresh the map. Assume the new extent is : -122. 5, 37.8, -122.4, 37.9. We need to send the ArcXML request like this:

<ARCXML version="1.0">
 <REQUEST>
  <GET_IMAGE>
   <PROPERTIES>
     <ENVELOPE minx="-122.5" miny="37.8" maxx="-122.4" maxy="37.9"/>
   </PROPERTIES>
  <GET_IMAGE>
 <REQUEST>
</ARCXML>

First we need to construct a document. In JAXP, it is obtained by using DocumentBuider in package javax.xml.parsers. Each Element is created by the Document and then added to the tree structure using the interface defined in W3C DOM level1 specification:


import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
...
    DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
    DocumentBuilder builder=dbf.newDocumentBuilder();
    Document doc=builder.newDocument();
    Element arcxml = doc.createElement ("ARCXML");
    arcxml.setAttribute("version","1.0");
    doc.appendChild(arcxml);
    Element request=doc.createElement("REQUEST");
    arcxml.appendChild(request);
    Element get_Image=doc.createElement("GET_IMAGE");
    request.appendChild(get_Image);
    Element properties=doc.createElement("PROPERTIES");
    get_Image.appendChild(properties);
    Element envelope=doc.createElement("ENVELOPE");
    properties.appendChild(envelope);
    envelope.setAttribute("minx","-122.5");
    envelope.setAttribute("miny","37.8");
    envelope.setAttribute("maxx","-122.4");
    envelope.setAttribute("maxy","37.9");
...

After the document is constructed , we need to send the document to ArcIMS Server for processing. JAXP provides a set of API in package javax.xml.transform, javax.xml.transform.dom, and javax.xml.transform.streams for transforming XML. Assume we are using Servlet Connector:

...
   String path="/servlet/com.Esri.Esrimap.Esrimap?ServiceName=SanFrancisco";
   URL imsURL = new URL("http","localhost", 80, path);
   URLConnection connection = imsURL.openConnection();
   connection.setDoOutput(true);
   connection.setDoInput(true);
   PrintStream out = new PrintStream(connection.getOutputStream());
   TransformerFactory tff=TransformerFactory.newInstance();
   Transformer tf=tff.newTransformer();
   tf.transform(new DOMSource(doc),new StreamResult(out));
...

The document is sent to an OutputStream. After the request is done, the Application Server will send the response back through a Stream. One of the typical response will be:

<?xml version="1.0">
 <ARCXML version="1.0">
  <RESPONSE>
   <IMAGE>
<ENVELOPE minx="-122.5" miny="37.8" maxx="-122.4" maxy="37.9"/>
<OUTPUT file="F:\MAP_A14829.jpg" url="http://localhost/maps/MAP_A14829.jpg"/> </IMAGE>
</RESPONSE>
</ARCXML>

the DocumentBuilder will build a Document from the InputStream, then we can retrive the information of interest (such as url of the generated image) by traverse the document tree:

...
   BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
   Document result=builder.parse(in);
   Element output=(Element)result.getElementsByTagName("OUTPUT").item(0);
   String imageURLString = output.getAttribute("url");
...

The retrieved imageURLString, along with other state variables of the session, can be embedded into a HTML page and sent back to the browser.

The first impression of the above approach might be too complex. However, as the size of the application grows, the advantage of object-orientated programming will soon pay off, especially for complex response such as a large set of geocoding results.

3.2.2 Using a specific DOM implementation.

The JAXP approach offers a platform level solution, independent of a particular flavor of parser. The application can use a different parser without changing the code, provided it is JAXP compliant. On the other hand, using a specific DOM implementation has its own advantages too, it may simplify the development cycle since most popular parsers offers some convenient methods to handle the DOM.

There are a number of XML parsers available, most of them are free for use. The most popular parsers include ProjectX (crimson) parser from Sun, Xerces parser from Apache, XMLParserV2 from Oracle, etc. ArcIMS uses Xerces and ProjectX parser. All parser packages have a set of concrete class that actually implement the W3C DOM interface. We will use Oracle parser as an example:

First we build the document, Oracle parser provides constructors for the implementation class:

...
import oracle.xml.parser.v2.*;
...       
    XMLDocument doc=new XMLDocument();
    XMLElement arcxml = new XMLElement("ARCXML");
    arcxml.setAttribute("version","1.0");
    doc.appendChild(arcxml);
    XMLElement request=new XMLElement("REQUEST");
    arcxml.appendChild(request);
    ...
    XMLElement envelope=new XMLElement("ENVELOPE");
    properties.appendChild(envelope);
    envelope.setAttribute("minx","-122.5");
...

Second we send request to ArcIMS server, Oracle parser provides a output method "print()" for transfer the DOM tree to an OutputStream:

...
    PrintStream out = new PrintStream(connection.getOutputStream());
    doc.print(out);
...

Finally we parse the result and get the information:

...
    BufferedInputStream in=new BufferedInputStream(connection.getInputStream());
    DOMParser parser=new DOMParser();
    parser.parse(in);
    XMLDocument result=parser.getDocument();
    XMLElement output=(XMLElement)result.getElementsByTagName("OUTPUT").item(0);
    String imageURLString = output.getAttribute("url");
...

Generally speaking, methods of building a DOM tree are very similar among different parsers, the output methods, however, vary from one another. For example, ProjectX parser uses writeXml() and writeChildrenXml(); Oracle parser uses print(), and Apache parser uses a whole serialize package to output the document.

3.2.3 W3C DOM with Customized Behavior.

Using JAXP or a W3C DOM implementation can build full ArcIMS application on server side. However, it may look a little bit unfamiliar from the perspective of a GIS application developer. Using a customized DOM can make the programming easier, and the final code will be much more readable. For example, instead of write code like this:

...
     Element envelope=doc.createElement("ENVELOPE");
     envelope.setAttribute("minx","-122.496415");
     envelope.setAttribute("miny","37.728692");
     envelope.setAttribute("maxx","-122.384637");
     envelope.setAttribute("maxy","37.794956");
...

We would prefer to write code as:

...
    Envelope envelope=new Envelope(-122.5, 37.7, -122.4, 37.8);
...

Apparently using a customized DOM can simply the application development. But how to build such customized DOM? In general we can extend a specific implementation of W3C DOM. For example, extend the ElementNode class from Sun’s XML packages.

Sun developed its XML packages under ProjectX (product now named "crimson"). One of the most important class in the packages is ElementNode, which allows to be subclassed for custom behaviors. We can build our customized DOM by extending this class. For example, build a class named Envelope matching the ENVELOPE tag in ArcXML:

  import org.apache.crimson.tree.*;  // com.sun.xml.tree.*;
  public class Envelope extends ElementNode {
      public Envelope(){
          setTag("ENVELOPE");
      }
      public Envelope(double minx, double miny, double maxx, double maxy){
          setTag("ENVELOPE");
          setMinx(minx);
          setMiny(miny);
          setMaxx(maxx);
          setMaxy(maxy);
      }
      public void setMinx(double minx) {
          setAttribute("minx", String.valueOf(minx));
      }
      public double getMinx() throws NumberFormatException {
          return Double.parseDouble(getAttribute("minx"));
      }
      ...
 }

By providing customized behaviors for tags, we can develop some very useful functions. For example, if a spatial query returns multiple features, and we want to view all of them, we need to get the combined extent of all features. We can define a function union in class Envelope:

...
    public Envelope union(Envelope anotherEnv){
       double minx=Math.min(this.getMinx(), anotherEnv.getMinx());
       double miny=Math.min(this.getMiny(), anotherEnv.getMiny());
       double maxx=Math.max(this.getMaxy(), anotherEnv.getMaxy());
       double maxy=Math.max(this.getMaxy(), anotherEnv.getMaxy());
       return new Envelope(minx, miny, maxx,maxy);
     }
...

During the processing of the returned Features, we go through the results, retrieve the Envelope of each Feature, and create the combined Envelope:

...
    Iterator iterator= featureList.iterator();
    while (iterator.hasNext()){
       Envelope ev=((Feature)iterator.next()).getEnvelope();
       allEnv = allEnv.union(ev);
    }
...
    myMap.zoomToExtent(allEnv);
...

The constructed document can be sent to an OutputStream which links to the application server. This is one side of the story, the other side is: after the processing is done, we need to use a parser to build a customized document. The Sun xml provides a special utility for this task: set a ElementFactory for the DocumentBuilder. During the parsing process, when the parser encounters an Element, instead of generating a regular instance of ElementNode, it will create a customized Element, for example, an instance of Envelope. The code is:

import org.apache.crimson.tree.*;  // com.sun.xml.tree.*;
import org.apache.crimson.parser.*;  // com.sun.xml.parser.*;
...
  SimpleElementFactory  factory=new SimpleElementFactory();
  factory.addMapping(tag2class, null);  //  null indicates the default ClassLoader
  XmlDocumentBuilder builder = new XmlDocumentBuilder();
  builder.setElementFactory(factory);
  Parser parser =new Parser();  
  parser.setDocumentHandler(builder);
...
  parser.parse(new InputSource(connection.getInputStream()));
  XmlDocument doc = (XmlDocument)(builder.getDocument());
  ServiceInfo info=(ServiceInfo)doc.getElementsByTagName("SERVICEINFO")Item(0);
...

In the above sample, tag2class is an instance of java.util.Dictionary, either a java.util.Hashtable or a java.util.Properties , which maps the ArcXML tag as key and their corresponding subclass name as value. The SERVICEINFO tag in the result document can be cast to an instance of ServiceInfo, and we easily access the information of the map service randomly, such as get the fields, id, name information about a particular layer.

Subclassing the implementation class of a W3C DOM provides a very powerful yet flexible way to develop ArcIMS application with ArcXML. However, W3C DOM is designed for a language independent standard, a lot of functionality will probably never be used in the development of an ArcIMS application. Based on these considerations, we can build a simple DOM specifically for ArcXML.

3.2.4 ArcXML Document Object Model

ArcXML is very simple, so we need a simple DOM. ArcXML (The public tags used for mapping request/response) does not have much content in the tags. Information is embedded in attributes. We can easily define what we need for an ArcXML tag: a tag name, a list of attributes, and a list of subtags. We also need a set of methods to access the attributes and subtags, for example, set/get the attribute value given the attribute name, add/get subtag etc. Another important feature is the ability to convert to a ArcXML String, because the Application Server is expecting a String and a String is easy to debug. An abstract class can be easily built for all ArcXML tags, using Java2 collection framework. Then we can use the DTD as a reference to build subclasses that correspond to each ArcXML tag. It is similar to subclassing a W3C DOM, and the abstract class for all ArcXML tags is a simplified W3C Element. For example, a sample diagram can be:

Figure 4: sample diagram of a simple DOM for ArcXML.

Building a response simple DOM is a little different from building a W3C DOM using a DOM parser or builder. In general we need to use a SAX parser and implement the org.xml.sax.DocumentHandler(SAX1)or org.xml.sax.ContentHandler(SAX2) interface. SAX parser is an event driven API for XML parsing. It will fire a series of events as the parser encounters different content from a Stream. With similar idea of ElementFactory, we could create tag specific element instance, and put them into a container such as a java.util.Stack. A First-In-Last-Out (FILO) algorithm can be used to build the hierarchy tree. After the parsing event, the objects in the container can be retrieved for use. For example:

... //SAX2:
  public void startElement(java.lang.String namespaceURI, java.lang.String localName,
         java.lang.String qName, Attributes atts) throws SAXException {
         AXLElement newElement=AXLElementFactory.createAXLElement(localName);
         ...
         for (int i=0; i<atts.getLength(); i++)
              newElement.setAttribute(atts.getLocalName(i), atts.getValue(i));
         ...   
         (AxlObject)(stack.peek()).addSubTag(newElement);
         stack.push(newElement);
   }
...

3.2.5 ArcXML Objects

Any Document is a tree of elements, and the elements have a set of attributes in the form of name-value pairs, and they are all saved as String. To retrieve an attribute, we need to iterate through the attribute set, find the matching attribute name, get the value, and then convert the value into a primitive type such as an integer. To retrieve a subtag, we need to iterate through the subtag set to find the matching subtag. The DOM approach provides a very portable way to handle ArcXML, however, it can be faster if not having to go through a tree to get a node and smaller if information was stored as primitive type in memory. For example, for an object of type Get_Features, we can store a set of boolean values instead of a list of name-pair objects. We can also take Subtags as member variables of a class, rather than objects in a collection. By this way, a reference of the target object or the value of the attribute can be returned immediately, without iterating the tree and comparing at each step. The classes developed this way do not depend on an Document model. For example:

  public class Get_Features extends java.lang.Object {
      Boolean attributes= true;  
      int beginrecord= 0;
...
      String outputmode="newxml";
      Layer layer=null;
      Query query=null;
      SpatialQuery spatialQuery=null;
...
      public void setBeginRecord(int b){
          beginrecord=b;
      }
...
      public Layer getLayer(){
          return layer;
      }
   

Same as those classes extending DOM, we must find a way to export the objects to XML representations, and a way for an XML parser to build objects from XML representations. These can be coded into a common interface, and all ArcXML tag classes will implement this interface. For example, the interface can define a method called toAxlString(), and all classes implemented this interface will "write XML by themselves".

  public interface AxlObject {
      public String toAxlString();
      public void add(AxlObject);
      public void setAttribute(String attrName,String attrValue) throws Exception; 
  }

All the ArcXML tags class should implement this interface, for example:

  public class  Envelope implements AxlObject {
      private double minx;
...
      public void setMinx(double minx){
           this.minx=minx;
      }
...
      public void add(AxlObject aobj){
      }
      public String toAxlString(){
          return "<ENVELOPE minx=\""+minx+"\" miny=\""+miny+"\" maxx=\""+maxx+"\" maxy=\""+maxy+"\"/>";
      }
      public void setAttribute(String attrName, String attrValue){
          if (attrName.euqals("minx")) setMinx(Double.parseDouble(arrValue);
          else if (attrName.euqals("miny")) setMiny(Double.parseDouble(arrValue);
          else if (attrName.euqals("maxx")) setMaxx(Double.parseDouble(arrValue);
          else if (attrName.euqals("maxy")) setMaxy(Double.parseDouble(arrValue);   
      }
  ...
  }

The major methods need to be implementd are: toAxlString(), which involves outputting/serializing objects to ArcIMS application server, and add(AxlObject) setAttribute(name, value), which involves building AxlObjects from ArcXML response streams from the application server. There are two possible ways to implement the interface: simply going through the member variables and perform the coresponsing get/set operations, or using the Java class reflection API (package java.lang.reflect). The first approach is easy and straight forward, like the sample code shown above, but the coding can be long and tedious(it is possible to generate most of the code automatically based on ArcXML DTD). The second approach is a "universal" solution but somehow complex. The following code is an experimental implementation of the toAxlString() method:

import java.lang.*;
Import java.lang.reflect.*;

Public class AnyArcXMLTag implements AxlObject {
        String tagName;
..
    public String toAxlString(){
        Boolean hasChild=false;
        StringBuffer buf=new StringBuffer();
        buf.append("<"+tagName+" ");
        // first export attributes
        Field[] fields=this.getClass().getDeclaredFields();
        for (int i=0; i< fields.length; i++){
            Field field=fields[i];
            Object obj=null;
            String mName="get"+Character.toUpperCase(field.getName().charAt(0))
                          +field.getName().substring(1);
           try{
              Method method=this.getClass().getMethod(mName, null);
              obj=method.invoke(this, null);
           } catch (Exception e){ e.printStackTrace();}
           if (obj!=null && !(obj instanceof AxlObject||obj instanceof java.util.List)){ // attribute
                buf.append(field.getName()+"=\""+obj+"\" ");
           } else if (obj !=null){
                hasChild=true;
           }
        }
        if (hasChild){
            // then export subtags
            buf.append(">\r\n");
            for (int i=0; i< fields.length; i++){
                Field field=fields[i];
                Object obj=null;
                String mName="get"+Character.toUpperCase(field.getName().charAt(0))
                             +field.getName().substring(1);
                try{
                    Method method=this.getClass().getMethod(mName, null);
                    obj=method.invoke(this, null);
                } catch (Exception e){ e.printStackTrace();}
                if (obj instanceof AxlObject){  // subtag with single entry
                    buf.append(((AxlObject)obj).toAxlString());
                } else if (obj instanceof java.util.List){  // subtag with mutiple entry
                    java.util.Iterator it=((java.util.List)obj).iterator();
                    while (it.hasNext()){
                        buf.append(((AxlObject)it.next()).toAxlString());
                    }
                }
            }
            buf.append("\r\n");
        } else {
            buf.append("/>\r\n");
        }
        return buf.toString();
    }

The approach of building generic Java classes for XML is related to the concept of Data-Binding from Sun, which will become a new standard for XML processing in Java Platform. The project "Adelard" is undergoing in the Java Community Process. The final product, called an XML data-binding facility, contains a schema compiler, which translates a schema into a set of schema-specific classes with appropriate access and mutation methods. It also contains a marshalling framework, which supports unmarshalling of XML documents into graphs of interrelated instances of both existing and schema-derived classes and marshalling of such graphs back into XMLdocuments. (XML documents from Sun). This technology can be applied to ArcXML once these utilities are available.

4. Framework of a JSP implementation.

JavaServer Pages(TM) is the Servlet extension of J2EE platform. Its framework separates presentation from content generation. As a result, JSP authors or web designers can take full advantage of the popular web authoring tools such as Macromedia Dreamweaver, Microsoft Front-page to modify the look and feel of the pages without worry about how the maps are generated, and GIS developer can focus on building requests to ArcIMS server and content generation without having to embed the presentation code into the content code. Cascading Style sheet (CSS) can also be embedded into the application.

4.1 Basic Components

A JSP ArcIMS solution can be created by the following components:

4.2 Object Sharing and Bean Scope

During an ArcIMS application initialization, the client will need information about a particular map service, the service info. In general the client will make a GET_SERVICE_INFO request to the ArcIMS server. The client needs to parse the returned result and set up the initial map parameters. If the map config is complex, this process can take a while. However, the service info for a map service is same unless the map service is updated, there is no need for each client / session to make such requests. Also, connectors can be shared by multiple session objects as long as one thread is using it at one time. Based on the above considerations, we can create an object that functions as the container for shared objects, including connectors and ServiceInfos.

Each object has its own life cycle. JSP specification provides four different options for the scope of a JavaBean: page, request, session and application. The map class, which stores persistence information of a user, should be in session scope. The optional Bean handling the transfer of HttpRequest, should be in a page scope or request scope, and the container class, which stores objects shared by multiple sessions and JSP pages, should be in application scope. See the following diagram:

Figure 5: Objects and their scope in a JSP page.

4.3 Work Flow of a Typical Request in a JSP Page with Object Pooling

Let's go through a typical http request made to an ArcIMS application developed using the framework outlined above. The web server redirects the request to JSP engine and the _jspService() method of the underlying JSP servlet is invoked. The servlet will first create a Bean object, set its attributes to the parameters specified in the HttpServletRequest object. Then the servlet will search for an application scope object "pool". If the "pool" is not already there, the servlet will create one and fill it with some connectors. This has to be done just once after the JSP engine is started. Then the servlet will search if there is a map object in this session. If no, in general it means this is the first time this user visits the site. A new instance of map object will be created and stored in the session. After the map object is created, it needs to be initialized, with information in the ServiceInfo object associated with this map service. The servlet will try to get the ServiceInfo object from the pool. If it is not in the pool, usually it means that no other user has visited that map service before, the servlet will make a GET_SERVICE_INFO request to ArcIMS server and get a ServiceInfo object, then put it into pool for future use. This needs to be done once for each map service. The time saved is substantial. After ServiceInfo object is obtained, the map can be initialized. LayerList object, extent, acetate layer objects can be initialized. If the map object is found in the session object, in general it means the user has hit the site before the last session expires, the map object can be retrieved from the session and ready to use. Then the servlet will process the request, either zoom, pan or query, construct ArcXML request, and parse result, update the session. To reduce session object serialization size, the serviceInfo member variables can be set to null after each request and reset from pool at next request. The updated map session object can be displayed in a JSP page.

 4.4. JSP pages for presentation/display

The actual look and feel is controlled by the JSP pages, which are responsible for display the content. For a regular web site, We need to have the following pages: basemap.jsp, for display the map image, legend, layer list, and other map tools; identify.jsp, for display the identify results, a "drill down" identify for multiple layers can be done in a single browser-web server traffic. search.jsp/query.jsp, for query the features, some of the components can be replaced by JDBC for faster and more powerful query. geocode.jsp, for geocoding; render.jsp, for thematic mapping; and services.jsp, for generic mapping a specific map service on a specific map server. As the following flow chart:

Figure 6: flow of a typical http request in a JSP solution.

4.5 Sample screen shots

The following images are taken from an actual implementation of the architecture outlined above.

Figure 7: Screen shot: basemap.jsp

Figure 8: Screen shot: query.jsp

Figure 9: Screen shot: identify.jsp

Figure 10: Screen shot: render.jsp

Figure 11: Screen shot: services.jsp

Figure 12: Screen shot: geocode.jsp

5. Conclusion

Server-side application is secure, light-weight and easy to customize and maintain. It is also more efficient to build a scalable and portable ArcIMS application, using XML technology at a Java Server context. Programmers can take full advantage of ArcIMS's XML based open architecture, plus all the power of Java Server side technology such as JSP/Servlet, JDBC, etc.

Acknowlegements


Endnotes

References


Nianwei Liu, City of Celveland, (216)664-3466. <liunw@yifan.net>