public interface StandaloneDataSourceUsage
Note that we do still require servlet-api.jar
to be on the classpath of
standalone applications. This is only to satisfy class-loading requirements; there are
cases where running inside a servlet engine allows us to provide extra functionality, such
as declarative authentication and authorization features, so some classes do have member
variables or method parameters of types in the Servlet API. They all operate correctly
when these variables or parameters are null, but the JVM will still try to load the classes
and will crash if they are missing.
Using the DataSource layer to run DataSource operations in your standalone applications is extremely straightforward. This example fetches and prints every record from the "customers" DataSource:
public static void main(String[] args) { DataSource ds = DataSourceManager.get("customers"); List records = ds.fetch(); for (Iterator i = records.iterator; i.hasNext(); ) { System.out.println(i.next()); } }To make this example fetch just customers in the United States:
Map criteria = new HashMap(); criteria.put("countryCode", "US"); List records = ds.fetch(criteria);This example shows how to run a specific fetch operation, specifying both selection criteria and a sort order, using a
DSRequest
rather than a DataSource
convenience method:
public static void main(String[] args) { DSRequest dsReq = new DSRequest("customers", "fetch"); dsReq.setOperationId("specialFetch"); Map criteria = new HashMap(); criteria.put("countryCode", "US"); criteria.put("region", "CA"); dsReq.setCriteria(criteria); dsReq.setSortBy("customerName"); List records = dsReq.execute().getDataList(); }This example shows how to do a simple update:
public static void main(String[] args) { DataSource ds = DataSourceManager.get("customers"); Map criteria = new HashMap(); criteria.put("customerNo", 12345); Map values = new HashMap(); values.put("creditLimit", 10000); values.put("currencyCode", "USD"); ds.update(criteria, values); }Finally, this example shows how to perform a specific update operation via a
DSRequest
:
public static void main(String[] args) { DSRequest dsReq = new DSRequest("customers", "update"); dsReq.setOperationId("specialUpdate"); Map criteria = new HashMap(); criteria.put("customerNo", 12345); Map values = new HashMap(); values.put("creditLimit", 10000); values.put("currencyCode", "USD"); dsReq.setCriteria(criteria); dsReq.setValues(values); dsReq.execute(); }NOTES
Because we are not running inside a servlet container, Smart GWT's built-in logic to
work out where its application root is does not work. Therefore, you need to manually
set a "webRoot" in your server.properties
file.
The webRoot should point
to the root folder of your application (note for SmartGWT applications, this is typically
the "war" subfolder of your project). Example entries:
webRoot: /home/testUser/myProject
or:
webRoot: C:\Projects\MyProject\war
Again in server.properties
,
you may need to set isomorphicPathRootRelative
to match the standalone project's layout if you make the standalone mode separate:
isomorphicPathRootRelative: myProject/sc
Note that the directory structure that normally appears in "war/myProject/sc" in your
GWT project is required to be present under the configured
webRoot+isomorphicPathRootRelative directory when running standalone. This
structure is
normally created by the GWT compiler, by processing <inherits> tags in your .gwt.xml
that cause resources to be copied from smartgwtee.jar. If your build/deployment scripts do
not invoke the GWT compiler these files will not be present, so you will need to either add
a step to invoke the GWT compiler or manually copy the files.
You should place the server.properties
file
somewhere on your classpath.
Typically, the root of your bin
or classes
folder structure is
the most suitable place for it.
Both the built-in DataSources and custom DataSources can be used in standalone applications, but only if you do not introduce dependencies on the servlet container in your DataSource code. For example, if you have a security check in a DMI or custom DataSource that depends on checking the current logged-in user, code in a means of bypassing this, or create a parallel operationBinding that is accessible only to the superuser.
When you use the DataSource layer in a standalone application,
Declarative
Security
is disabled; all operations
are considered to be valid for use in a standalone application. Other DataSource features
that are disabled because they are not relevant in a standalone context are:
Transaction Chaining
Transactional
persistence
In a typical web application, Spring configuration is picked up from an "applicationContext" file by a servlet or listener, and then made available to the rest of the app via the servletContext. When running standalone, this is not possible, so instead we read the applicationContext file manually when we need to, eg, create a DataSource object that is configured as a Spring bean.
By default, the framework will look in the "normal" place for for this configuration:
WEB-INF/applicationContext.xml
. If you have changed the location or name
of this file, and you want to run the application outside of a servlet engine, you can tell
the framework where to find the configuration file by specifying property
standalone.spring.applicationContext
in your server.properties
.
The default setting for this property looks like this:
standalone.spring.applicationContext: $webRoot/WEB-INF/applicationContext.xml