This page is the starting point for learning about the Directory Listing application. The following topics are covered:
The Directory Listing sample application was created to complement the use of the dojox.data.FileStore store from the Dojo Toolkit for JavaScript. The Directory Listing sample demonstrates how to develop a JAX-RS Representational State Transfer (REST) application that can receive and respond to requests originating from the dojox.data.FileStore data store.
The dojox.data.FileStore data store is a lightweight JavaScript implementation for accessing details about a remote file system. This data store and the server side JAX-RS resource do not inflate the entire hierarchy of the requested file system path. This allows it to quickly return information for the requested path while providing hooks for lazy loading the subdirectories. This is an example of how a Dojo data store can do lazy loading, and how to create the JAX-RS resource that conforms to the expectations of the dojox.data.FileStore.
The primary purpose of this Directory Listing sample is to demonstrate the simplicity and capability of the JAX-RS resource class. However, to fully demonstrate this simplicity, the dojox.data.FileStore data store is included in a larger Dojo application. Read about writing the Directory Listing application for an example.
Product prerequisite | Version |
---|---|
Java Technology Edition | 5.0 and later |
Java Platform, Enterprise Edition 5 (Java EE) application server and later | WebSphere Application Server Version 6.1.0.x and later WebSphere Application Server Community Edition Version 2.X. |
Web browser | Any modern web browser, such as: Internet Explorer 7 and later Mozilla Firefox 3.x and later Google Chrome Safari Opera |
Develoment IDE (Optional) | Eclipse version 3.X |
The Directory Listing sample application is not intended for deployment to production servers. It is for development and educational purposes only.
All source code for the JAX-RS application, resource, and Web pages is provided as is for you to use, copy, and modify without royalty payment when you develop applications that run with WebSphere software. You can use the sample code either for your own internal use or for redistribution as part of an application, or in your products.
The design of the Directory Listing sample application demonstrates how to approach development of Ajax-based applications with the Dojo Toolkit in a Java EE environment. To meet these goals, the two parts of a Java EE application, the client side and the server side, are organized into simple operations that perform a useful function. It follows the basic pattern that Java EE applications use when incorporating Ajax technologies.
The following sections assume that you are already familiar with the JavaScript framework for Dojo, and do not explain in detail the sample Dojo client application or the Dojo dojox.data.FileStore data store that is being used.
The client is the web page that is served to the browser. In the web page, the dojox.data.FileStore data store is instantiated and declared as the store to a dijit.tree.ForestStoreModel, which is declared as the model to a dijit.Tree widget. The dijit.Tree widget provides the visual representation of the file system hierarchy. It provides plus and minus symbols next to the directories in the tree that users click to expand or contract. When the user clicks the plus symbol, the requested path is passed to the JAX-RS resource by the dojox.data.FileStore data store and performs the lazy loading feature. For more specific information about the client side design read about the client side design of the Directory Listing sample application.
The server provides the infrastructure for processing services and serving Web pages. In this application, the server side is a JAX-RS resource class that receives and processes GET queries from the dojox.data.FileStore data store, and responds according to the requirements of this data store and the enclosing Dojo application. For more specific information about the server side design, read about the server side design of the Directory Listing sample application.
The Directory Listing sample application uses the dojox.data.FileStore data store to query the JAX-RS resource for information about a path on the server's file system. The dojox.data.FileStore object is configured with an options string, a URL to the service, and the pathAsQueryParam flag to indicate that the path being requested should be sent as a ?path=/the/path query parameter. Without this flag, the request would be sent as an appendage to the URL.
The application built around the dojox.data.FileStore, model, and tree, includes dojo.form.CheckBox widgets to enable or disable support of individual features of the dojox.data.FileStore data store. They are included as part of the application to demonstrate the capability of the data store. Enabling or disabling a feature by clicking an individual checkbox requires that the data store resend the initial request to the server, and refresh the model and tree, which you will see as you test these features.
The search features of dojox.data.FileStore are also handled in the application. A file attribute available in a drop-down list can be selected along with text (including wild card asterisks) to do matching. The search can be further narrowed by selecting "Ignore capitalization" or "Deep search". Finally, to limit or control the amount of items returned in the search, the start index can be provided along with the count of the maximum number of entries that should be returned.
In addition to the expected features of a standard Dojo data store, model, and tree, the application calls a special feature of the JAX-RS resource to pre-populate a directory tree so the client renders a useful set of data. The application uses dojo.xhrPut to send a PUT request to the JAX-RS resource, indicating to the JAX-RS resource that it should populate a directory hierarchy for use by the sample.
The primary purpose of this Directory Listing sample application is to demonstrate the simplicity of getting a JAX-RS resource developed that can receive and process queries from the dojox.data.FileStore. Therefore, the exercise of understanding and coding the client is left to the reader. However, it should be noted that this client is written to use Dojo features programmatically to demonstrate all of the features of the dojox.data.FileStore and to eliminate the need to manually build up a file system hierarchy. The visual dijit.Tree, and its inclusion of the model and store could have also been written declaratively in just a few short lines of HTML code, shown here:
<div dojoType="dojox.data.FileStore" jsId="myStore" url="rest/directorylisting" pathAsQueryParam="true"></div> <div dojoType="dijit.tree.ForestStoreModel" jsId="myModel" store="myStore" rootId="myfiles" rootLabel="Files" childrenAttrs="children"></div> <div dojoType="dijit.Tree" id="mytree" model="myModel"></div>
For more information on how to use the client side, refer to the application source code. Each section in the HTML document is commented, explaining the purpose of the code block.
At a minimum, the Directory Listing sample application for the server must be capable of receiving a GET request with a path appended to the path listening for the request or a ?path=/myPath query parameter attached to the GET request. In an effort to make the setup of the sample as convenient as possible, the JAX-RS resource includes a method listening for PUT queries that will pre-populate a file system directory hierarchy so the Dojo client may call it prior to demonstrating the dojox.data.FileStore features. This eliminates the need to manually create a file system hierarchy.
The JAX-RS runtime environment has built-in capability of splitting any query parameters into their name/value pairs, and passing them as parameters to the Java method receiving the GET request.
package com.ibm.websphere.mobile.appsvcs.sample.directorylisting.resources; import javax.ws.rs.Path; // Full import list not shown. @Path("/directorylisting") public class DirectoryListingService { // ... }
Note that this JAX-RS resource class is declared to have a URL segment of "/directorylisting". This resource class will handle requests targeted at http://<server>:<port>/<context-root>/<uri-mapping>/directorylisting.
The context root is defined by the application.xml file if your web archive file (.war) is packaged in an enterprise archive (.ear) file. If the .war is installed by itself, the context root is defined at install time by the user. The uri mapping is defined in the WEB-INF/web.xml in the .war file.
The dojox.data.FileStore data store sends GET requests. In the client it has been configured to send the desired path as a query parameter and a subset of the various optional arguments described in dojox.data.FileStore, including the dojo.data.api.Read query protocol. For example, the dojox.data.FileStore data store might send a GET request as http://<server>:<port>/<context-root>/<uri-mapping>/directorylisting?path=/the/path. Given we need to handle the path as part of the URL and alternatively as query parameter, we have a JAX-RS resource method for each. They each call into a common method to handle the logic of the service.
// Query parameters and values private static final String QUERY_OPTIONS = "options"; private static final String QUERY_PATH = "path"; private static final String QUERY_QUERY = "query"; private static final String QUERY_QUERYOPTIONS = "queryOptions"; private static final String QUERY_START = "start"; private static final String QUERY_COUNT = "count"; // Default value for start and count query parameters. private static final String NO_VALUE_STRING = "-1"; private static final int NO_VALUE_INT = -1; @GET @Produces(MediaType.APPLICATION_JSON) public JSONObject getFileListWithPathInParam( @Context ServletConfig servletConfig, @Context HttpHeaders httpHeaders, // Note, the path is obtained with @QueryParam. @QueryParam(QUERY_PATH) String path, @QueryParam(QUERY_OPTIONS) String options, @QueryParam(QUERY_QUERY) String query, @QueryParam(QUERY_QUERYOPTIONS) String queryOptions, @DefaultValue(NO_VALUE_STRING) @QueryParam(QUERY_START) String startParam, @DefaultValue(NO_VALUE_STRING) @QueryParam(QUERY_COUNT) String countParam) { return getFileListCommon(servletConfig, path, options, query, queryOptions, startParam, countParam); } @GET // JAX-RS will call this method if the URL has more than the root path. @Path("{path:.*}") @Produces(MediaType.APPLICATION_JSON) public JSONObject getFileListWithPathInUri( @Context ServletConfig servletConfig, @Context HttpHeaders httpHeaders, // Note, the path is obtained with @PathParam. @PathParam(QUERY_PATH) String path, @QueryParam(QUERY_OPTIONS) String options, @QueryParam(QUERY_QUERY) String query, @QueryParam(QUERY_QUERYOPTIONS) String queryOptions, @DefaultValue(NO_VALUE_STRING) @QueryParam(QUERY_START) String startParam, @DefaultValue(NO_VALUE_STRING) @QueryParam(QUERY_COUNT) String countParam) { return getFileListCommon(servletConfig, path, options, query, queryOptions, startParam, countParam); }
The first @GET annotation declares that the method will receive HTTP GET requests at the URL ending with directorylisting per the class level @Path annotation. Note the use of the @QueryParam annotation to access the path being requested in the service.
The second @GET annotation further qualifies the @Path with a regular expression, "{path:.*}" which maps to any characters being present after the class level @Path annotation. Therefore, when the second method is called, the path is expected to be in the URL. Note the use of the @PathParam to access the value of the path being requested in the service.
Each of the two methods include the @Produces annotation. This helps the JAX-RS runtime match the inbound message with the Java method. The JAX-RS runtime will try to match the inbound message Accept header with the @Produces value. It also informs the JAX-RS runtime in what format the response should be.
At this point, one more class is required to complete the application. JAX-RS initializes an application and its resources and providers through the class that extends javax.ws.rs.core.Application. Therefore, create the following class.
package com.ibm.websphere.mobile.appsvcs.sample.directorylisting; import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; public class DirectoryListingApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(DirectoryListingService.class); return classes; } }
Below are the critical parts to enable this JAX-RS application.
... <servlet-name>JAXRSServlet</servlet-name> <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.ibm.websphere.mobile.appsvcs.sample.directorylisting.DirectoryListingApplication</param-value> </init-param> ... <servlet-mapping> <servlet-name>JAXRSServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> ...
Note the servlet-class and the init-param with param-name "javax.ws.rs.Application". This is the standard way to declare the servlet implementation and pass the reference of the class that extends javax.ws.rs.core.Application to the JAX-RS runtime.
With the inclusion of the WEB-INF/web.xml, the compiled application, and the proper library files in the WEB-INF/lib/ directory of the .war file, the application can be installed to an application server. See the contents of the included sample if you want to see the list of required libraries. The included sample application is in the form of a .war file packaged within a .ear file. Within the .ear file is the standard application.xml file, which specifies the URL context root of "/appsvcs-directorylisting". Thus, the URL to the index.html file is http://<server>:<port>/appsvcs-directorylisting/. Note that the URL specified in the index.html file in the sample application is rest/directorylisting, which is relative to the location of the index.html file, and is the result of the concatenation of the URL pattern in the web.xml file and the @Path annotation in the JAX-RS resource class.
The getFileListCommon method is called from each of the two JAX-RS resource methods described earlier. The list below describes each parameter. The format and content of the parameters aligns with the documentation for dojox.data.FileStore. The first two parameters are always provided by the underlying servlet container. The remaining parameters are optional. Therefore, you can specify null or accept the default values.
protected JSONObject getFileListCommon( ServletConfig servletConfig, HttpHeaders httpHeaders, String path, // Path of the request, from the URL or an HTTP parameter String options, // JSON array, could contain expand, showHiddenFiles, dirsOnly String query, // JSON array of name/value pairs for a filtered search String queryOptions, // JSON array of settings for a deep search and/or ignoreCase String startParam, // Index of results to start with in the returned list String countParam) // Number of items to return in the result list { // ... }
Methods exist in the source code to validate each of the parameters and in some cases put them into a form that is easy to query later. See the dojox.data.FileStore documentation for descriptions of these parameters.
At this point, you have successfully received the request from the dojox.data.FileStore data store. It expects a reply in JSON format, which can be constructed using information from the requested path in a JSONObject. The code sample below shows how to build the JSON formatted response.
// Attribute names private static final String ATTRIB_ITEMS = "items"; private static final String ATTRIB_NAME = "name"; private static final String ATTRIB_PATH = "path"; private static final String ATTRIB_PARENTDIR = "parentDir"; private static final String ATTRIB_SIZE = "size"; private static final String ATTRIB_DIRECTORY = "directory"; private static final String ATTRIB_CHILDREN = "children"; private static final String ATTRIB_MODIFIED = "modified"; ... // Assume you have already found the file you want, // instantiated as a Java file in variable "file" JSONArray fileList = new JSONArray(); if (path.equals("/") && file.isDirectory()) { // Query param "path" was not passed, was blank, or "/" File[] children = file.listFiles(); if (children != null && children.length > 0) { for (int i = 0; i < children.length; i++) { // Call common code to append the list if the file is acceptable. // This also searches recursively if necessary. appendFileList(children[i], fileList); } } JSONObject items = new JSONObject(); items.put(ATTRIB_ITEMS, fileList); logger.exit(); return items; } else { // This is a single identity lookup for a specific path. // A JSONObject representing the file will be returned. JSONObject jsonFile = appendFileList(file, null); if (jsonFile == null) { // Handle error ... } else { logger.exit(); return jsonFile; } } ... ... private JSONObject appendFileList(File file, JSONArray fileList) { ... JSONObject item = new JSONObject(); if (file != null) { item.put(ATTRIB_NAME, file.getName()); item.put(ATTRIB_MODIFIED, new Long(file.lastModified())); item.put(ATTRIB_SIZE, new Long(file.length())); item.put(ATTRIB_PATH, getFileAttribute(ATTRIB_PATH, file)); item.put(ATTRIB_PARENTDIR, getFileAttribute(ATTRIB_PARENTDIR, file)); item.put(ATTRIB_DIRECTORY, new Boolean(file.isDirectory())); // See the sample code for details on traversing directory trees of files ... // Add another item to the list. fileList.add(item); } ... }
At this point, we have a JAX-RS service resource capable of receiving and responding to the expectations of the dojox.data.FileStore data store. The implementation details of traversing the file system, managing the options from the options query parameter, and allowing configuration of the root directory are left for the reader to see in the source code.
The source code of the Directory Listing sample application is provided within the .war web module file within the appsvcs-directorylisting.ear file. There are two approaches to viewing the source code: through an Eclipse-based Integrated Development Environment (IDE) or by decompressing the appsvcs-directorylisting.ear file, then decompressing the .war file contained inside.
The first step in viewing the source code is locating the DirectoryListing.ear file. If you have installed the IBM WebSphere Application Server Feature Pack for Web 2.0 and Mobile, then you can find the EAR file in your installation tree.
For example, if you installed the feature pack in the following location:
Platform Location Linux and UNIX: /opt/WebSphere/AppServer z/OS mount point: <install_root> Windows: c:\WebSphere\AppServer
Then you can find the EAR file at:
Platform Location Linux and UNIX: /opt/WebSphere/AppServer/web2mobilefep_1.1/samples/directorylisting/appsvcs-directorylisting.ear z/OS: <install_root>/web2mobilefep_1.1/samples/directorylisting/appsvcs-directorylisting.ear Windows: c:\WebSphere\AppServer\web2mobilefep_1.1\samples\directorylisting\appsvcs-directorylisting.ear
Using an Eclipse-based IDE is the simplest approach to examining the source code of the WAR file. Use any Eclipse 3.2.X, 3.3.X IDE with the Web Tools Project 2.5 or higher, or Rational Application Developer, Version 7.0 or higher, can import the web archive (WAR) file when you complete the following steps:
When the import process completes, a new project, DirectoryListing, exists in the Eclipse workspace. The application source code can be accessed from the DirectoryListing project. To access the client or server code, see the following table for source code locations in the DirectoryListing Eclipse project tree.
Source Code | Location |
---|---|
Client side (web browser) | WebContent/index.html: Contains the Dojo Widget definitions and client script functions. This file loads the unoptimized Dojo profile. |
Server side | Java resources: src/com.ibm.websphere.mobile.appsvcs.sample.directorylisting/ DirectoryListingApplication.java: Double-click this file to load the source code. |
Java resources: src/com.ibm.websphere.mobile.appsvcs.sample.directorylisting. resources/DirectoryListingService.java: Double-click this file to load the source code. |
Web application archives are file archives compressed using the ZIP algorithm. Therefore, the archive file can be expanded by any number of tools for compressing files, including the Java archive (JAR) program. The following steps assume that the user chooses their favorite tool to create compressed files.
After you have expanded the EAR file contents, expand the .war file contents. Then you can access the source code. To access the client or server code, see the following table for source code locations in the EXPAND_DIR/DirectoryListing directory.
Source Code | Location |
---|---|
Client side (web browser) | index.html: Contains the Dojo widget definitions and client script functions. |
Server side | WEB-INF/classes/com/ibm/websphere/mobile/appsvcs/sample/directorylisting/ DirectoryListingApplication.java |
WEB-INF/classes/com/ibm/websphere/mobile/appsvcs/sample/directorylisting/ resources/DirectoryListingService.java |
Refer to the following version-specific installation instructions:
This section describes the procedure for installing the Directory Listing sample application on Version 6.1.0.X and later of the IBM WebSphere Application Server. It is assumed that you are familiar with application installation and administration for the application server.
Locate the Directory Listing sample application enterprise archive (EAR) file that is provided with your product installation. You can find the EAR file in your installation tree where you installed the IBM WebSphere Application Server Feature Pack for Web 2.0 and Mobile. For example, if you installed the feature pack in the following location:
Platform Location Linux and UNIX: /opt/WebSphere/AppServer z/OS mount point: <install_root> Windows: c:\WebSphere\AppServer
Then you can find the EAR file at:
Platform Location Linux and UNIX: /opt/WebSphere/AppServer/web2mobilefep_1.1/samples/application_services/directorylisting/appsvcs-directorylisting.ear z/OS: <install_root>/web2mobilefep_1.1/samples/application_services/directorylisting/appsvcs-directorylisting.ear Windows: c:\WebSphere\AppServer\web2mobilefep_1.1\samples\application_services\directorylisting\appsvcs-directorylisting.ear
- Log into the administrative console for the application server.
- Navigate to Applications > New Application. (Note: In WebSphere Application Server Version 6.1, select Install New Application)
- Select New Enterprise Application. (Note: In WebSphere Application Server Version 6.1, skip this step)
- Browse your file system, and select the appsvcs-graphics.ear file that you located earlier. Click Next.
- Click Next to prepare for the application installation. (Note: In WebSphere Application Server Version 6.1, skip this step)
- Click Next to accept the default installation options.
- Click Next to accept the default options for map modules to servers.
- Click Next to accept the default options for Metadata for modules. (Note: In WebSphere Application Server Versions 6.1 and 7, skip this step)
- Click Next to accept the default options for map virtual hosts for web modules.
- Review the summary of the installation options.
- Click Finish.
- Click Save to the master configuration.
- Navigate to Applications > Application Types > WebSphere Enterprise Applications. (Note: In WebSphere Application Server Version 6.1, Navigate to Applications > Enterprise Applications)
- Select the IBM WebSphere Application Server - Directory Listing sample application, and click Start.
Point your web browser to your application server installation: http://<application server hostname>:<port>/appsvcs-directorylisting/
The application server host name and port number are specific to your application server installation. An application server default installation web container port is 9080. If you are running your web browser on the same workstation as your application server installation and have taken all the default values, then use the following URL: http://localhost:9080/appsvcs-directorylisting/.
This section describes the procedure for installing the Directory Listing sample application into Version 2.X of the IBM WebSphere Application Server Community Edition. It is assumed that you are familiar with application installation and administration for the application server.
Locate the Directory Listing sample application enterprise archive (EAR) file that is provided with your product installation. You can find the EAR file in your installation tree where you installed the IBM WebSphere Application Server Feature Pack for Web 2.0 and Mobile. For example, if you installed the feature pack in the following location:
Platform Location Linux and UNIX: /opt/WebSphere/AppServerCommunityEdition Windows: c:\WebSphere\AppServerCommunityEdition
Then, you can find the EAR and library files at:
Platform Location Linux and UNIX: /opt/WebSphere/AppServerCommunityEdition/web2mobilefep_1.1/AppServices/samples/directorylisting/appsvcs-directorylisting.ear Windows: c:\WebSphere\AppServerCommunityEdition\web2mobilefep_1.1\AppServices\samples\directorylisting\appsvcs-directorylisting.ear
Log into the administrative console for the application server.
- Click Applications > Deployer in the left menu. (Note: In WebSphere Application Server Community Edition Version 2.0, click Applications > Deploy New)
- In the Archive field, browse your file system, and select the appsvcs-directorylisting.ear file that you located earlier. Leave the Plan field empty and the default options selected. Then, click Install.
The application starts automatically, and installation is complete.
Point your Web browser to your application server installation: http://<application server hostname>:<port>/appsvcs-directorylisting/.
The application server host name and port is specific to your application server installation. The WebSphere Application Server Community Edition server default installation Web container port is 8080. If you are running your browser on the same workstation as your application server installation and have accepted all the default values, then use the following URL: