In the following section it is assumed that you have knowledge how to build a normal Struts application and also a J2ME application. In addtion we assume that you have downloaded the binary distribution which contains the 3 jar files.
This document describes in general terms how to broaden your existing web application to support a mobile client. In the following we assume you have a existing Struts application called Yourapp .
The rest of the document will speak about the 3 modules.
Include the StrutsME-Server - and the Yourapp-Common-jarfile in the classpath of your server.
This could be done by one of the following options.
<controller
processorClass="org.strutsme.server.StrutsMERequestProcessor"/>
In the web.xml under the servlet entry for the StrutsActionServlet insert:
<init-param>
<param-name>packagePrefix</param-name> <param-value>foo.dto.</param-value> </init-param>
<dependency>
<groupId>strutsme</groupId>
<artifactId>cldcapi</artifactId>
<version>${wtk.cldc.version}</version>
<jar>cldcapi${wtk.cldc.version.maven}.jar</jar>
<type>jar</type>
</dependency>
<dependency>
<groupId>strutsme</groupId>
<artifactId>midpapi</artifactId>
<version>${wtk.midp.version}</version>
<jar>midpapi${wtk.midp.version.maven}.jar</jar>
<type>jar</type>
</dependency>
<dependency>
<groupId>strutsme</groupId>
<artifactId>strutsme-common</artifactId>
<version>SNAPSHOT</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>strutsme</groupId>
<artifactId>strutsme-client</artifactId>
<version>SNAPSHOT</version>
<type>jar</type>
</dependency>
This should be done for both the Common- and the ClientModule.
If required the actions (and so the JSPs) have to be changed so that all resulting data of an action, which are needed on the mobile client, are contained in the form.
If you want specific error messages from the exception you have to extend your exceptions from org.strutsme.server.BusinessException .
The client code can now call the action using org.strutsme.client.server.RemoteExecutor . The remote actioncall on the server must be implemented asynchron on the client. This means, the client cannot wait on the response of the server. Therefore a new thread is started for each remoteactioncall on the server. A sample is shown in listing Calling Action at Server 4. The listing is an extract of the sampleapplication StrutsME-Wishlist-Client in the package org.strutsme.client.adapter . The referenced runner in the listing has only to be implemented once for the clientapplication.
/**
* {@inheritDoc}
*/
public void loadWish() throws AdapterException {
SafeHashtable formParams = new SafeHashtable();
Hashtable actionParams = new Hashtable();
executeActionAtServer(GbCommonConstants.ACTION_WISH_LIST_WISHES,
actionParams, formParams);
}
/**
* {@inheritDoc}
*/
public void saveArticle(final ArticleDtoImpl article)
throws AdapterException {
SafeHashtable formParams = new SafeHashtable();
Hashtable actionParams = new Hashtable();
// put the article into the formData -> see
// ArticleForm in the \yourappserverapplication
formParams.put("article", article);
formParams.put("body", article.getBody());
formParams.put("subject", article.getSubject());
String action = GbCommonConstants.
ACTION_ARTICLE_SAVE_ARTICLE;
executeActionAtServer(action, actionParams,
formParams);
}
/**
* execute the action at the server.
* @param action the action to perform
* @param actionParams the actionparams for the server
* @param formParams the formParams, which contains
* the real contentinformation
* @throws AdapterException if the action could not
* be executed properly
*/
private void executeActionAtServer(final String action,
final Hashtable actionParams,
final SafeHashtable formParams)
throws AdapterException {
resetConnectionState();
Thread thread = new Thread(new WishOnlineRunner(this,
action, actionParams, formParams));
thread.start();
}
package org.strutsme.wishlist.client.adapter;
import java.util.Hashtable;
import org.strutsme.client.RemoteExecutor;
import org.strutsme.client.ServerResultWrapper;
import org.strutsme.common.SafeHashtable;
import org.strutsme.wishlist.client.control.ActionDispatcher;
import org.strutsme.wishlist.client.forms.FormTools;
import org.strutsme.wishlist.common.GbCommonConstants;
/**
* Connections should be performed in seperate Threads to avoid deadlock. This
* Runner handles all requests of the Wishlistapplication.
* @author lbusmann
*/
public final class WishOnlineRunner implements Runnable {
/**
* the adapter, which started this runner.
*/
private final WishOnlineAdapter adapter;
/** the name of the action to perform. */
private final String action;
/** the requestParams for the action. */
private final Hashtable requestParams;
/** the content (formData) of the Action. */
private final SafeHashtable formData;
/**
* Constructor.
* @param action the action to perform
* @param requestParams the requestParams
* @param formData the formData
* @param adapter the adapter, which started this runner
*/
public WishOnlineRunner(final WishOnlineAdapter adapter,
final String action, final Hashtable requestParams,
final SafeHashtable formData) {
this.adapter = adapter;
this.action = action;
this.requestParams = requestParams;
this.formData = formData;
}
/**
* {@inheritDoc}
*/
public void run() {
try {
final SafeHashtable response = RemoteExecutor.executeAtServer(action
+ GbCommonConstants.ACTION_EXTENSION, requestParams,
this.adapter.getSessionId(), formData);
this.adapter.setLastServerResponse(new ServerResultWrapper(response));
} catch (final Exception e) {
FormTools.showErrorAlert("Wishlist",
"Can't connect to the server.\n\n"+e.getMessage());
}
ActionDispatcher.getInstance().executeResponseAction();
}
}
Note that the WishOnlineRunner
is calling the
Actiondispatcher.getInstance().executeResponseAction()
, which would process the response of the server.
This section contains information about known bugs or limitations of StrutsME .
Except for the session-id cookies are not handled. This could be improved by for example storing server cookies at the client in the RMS and sending these transparently to the server. The current solution for the application developer is to make sure that the web application also works without cookies.