Sending Server Requests and Custom Actions
In addition to executing code in the user’s browser, a JMap Web extension may define actions that can leverage JMap Server’s API. These actions will be registered against your deployment’s AJAX Dispatcher service and may be triggered via HTTP requests.
A JMap Web extension can contain several actions. You also may create additional non-action classes that will be referenced within your actions.
Creating an Action
Create a class that inherits from AbstractHttpRequestAction. To follow along this example, the name of your class should be MyFirstAction.
package myextension;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jmap.http.ajax.servlets.AbstractHttpRequestAction;
public class MyFirstAction
extends AbstractHttpRequestAction
{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException
{
}
}
As you may have noticed, the action requires the HttpServletRequest and HttpServletResponse classes in order to compile. Add Tomcat server’s servlet-api JAR to your build path. That particular JAR file may be found within the $JMAP_HOME
$/tomcat/lib directory.
An action requires an execute
method. That method will be called whenever an HTTP request specifically requesting your action is received by the AJAX Dispatcher.
For the purposes of this example, the following is a typical Hello World! action.
package myextension;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jmap.http.ajax.servlets.AbstractHttpRequestAction;
public class MyFirstAction extends AbstractHttpRequestAction
{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response)
throws IOException
{
final PrintWriter writer = response.getWriter();
String name = request.getParameter("name");
if (name != null && name.trim() != "")
writer.print("Hello, " + name);
else
throw new IllegalArgumentException("Invalid argument. Must specify anameparameter.");
}
}
Producing a JAR File for Your Action
In order to be included as part of a JMap Web extension, your server-side Java code must be compiled and packaged as a single JAR file.
Using Ant
When using JMap 6.0 SDK’s webextensionbuilder tool (described in the Programming JMap Web Extensions section) to produce an extension’s boilerplate code, a SampleAction is provided as a starting point. A build.xml file is also provided. You can use that file with Ant to compile and produce your extension’s JAR file.
Copy your MyFirstAction.java file to your extension’s actions/src directory. Since the MyFirstAction class is defined within the myextension package, create a myextension directory under actions/src and put your MyFirstAction.java file in it. At this point, you should have the following items in your actions directory:
actions/
├── build.xml
├── readme.markdown
└── src
├── Example
└── SampleAction.java
└── myextension
└── MyFirstAction.java
3 directories, 4 files
Using the command line/terminal navigate to your extension’s actions directory and execute the following command.
ant -f build.xml
Once you have your JAR file, make sure it’s in your web extension’s actions directory.
Using Ant through Eclipse
As was the case when using the web extension builder tool, you may use Ant through Eclipse to produce your extension’s server jar file. This requires that a JDK is set as Eclipse’s default JRE and that the JDK’s tools.jar file is added to the Ant runtime configuration’s classpath. These steps were previously detailed here.
Open the your extension’s actions/build.xml file in Eclipse.
Execute the “package” ant target.
Once you have your JAR file, make sure it’s in your web extension’s actions directory.
Identifying Your Extension’s Actions
As part of your extension, the extension.json file informs JMap Server about itself. You must now indicate that the extension contains actions. Open that file in a text editor.
The actions property is an array that can contain several object literals each describing individual actions.
The actions array’s object literals must have the following property keys:
name | {String} This is the name of the action as it will be registered against the AJAX Dispatcher. Must be unique within a single JMap Web deployment. HTTP requests must specify this value for the action request parameter. Does not need to correspond to your action’s class’s source file name. |
classname | {String} The fully qualified name of your class. Must include packages. |
version | {String} Specifies a version. Mostly useful for debugging purposes. |
This snippet is how you would represent the MyFirstAction action as part of the web_sdk_documentation_example extension that was created earlier:
{
"actions": [
{
"name": "hello",
"className": "myextension.MyFirstAction",
"version": "1.0.0"
}
],
"fullname": "Web SDK Documentation Example",
"namespace": "Example",
"shortname": "web_sdk_documentation_example",
"version": "1.0"
}
Your extension may include as many actions as you want. Just be sure to include them within your extension’s extension.json file.
After editing the extension.json file, be sure that it contains valid JSON. JSONLint is an online JSON validator that can be used for that purpose.
Calling your action from your JMap Web Extension
As previously mentioned, your action’s execute method will be called once the AJAX Dispatcher receives an HTTP request that specifies your action’s name as a parameter.
The following example demonstrates how you can submit an HTTP Request to your action using jQuery.ajax(). To test this, you can either include this snippet in your extension’s init function or copy and paste it in a browser’s Javascript console currently logging your deployed application.
$.ajax(JMap.app.ajaxDispatcher,{
data: {
"action": "hello", // The action name as defined in the extension.json file.
"name": "Developer" // The name parameter as expected by the action.
}
}).error(function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}).success(function(data, textStatus, jqXHR) {
alert(data);
});
Dernière mise à jour