@WebServlet(description="SIMRacingApps Data Access for JSON",
urlPatterns={"/Data","/Data/*"},
loadOnStartup=1)
public class Data
extends javax.servlet.http.HttpServlet
There are 2 ways to use these methods. One is Subscribe and Publish and the other is ReST(Representational State Transfer).
Subscribe and Publish
This process uses the POST method to subscribe to the data to publish.
The GET method is then used to poll the server for the published changes.
Through other HTTP interfaces, you can also use
Web Socket Polling
,
Web Socket Streaming
,
and Web Events
to receive the published changes.
Both POST and GET must have a parameter called "sessionid", in the URL query string, with a value that will be used to identify who the subscriptions below to. Depending on the client, you may want to disable caching by adding a counter parameter that is incremented on every call to GET. To help out, the response headers are also set to disable caching. For example: http://localhost/SIMRacingApps/Data?sessionid=1234567890. I would recommend using a value that will not conflict with other clients using the server at the same time, like time of day down to the millisecond.
The body of the POST method must be formatted as a JSON string according to the following structure. This same structure will be updated with the values and returned to you when you call GET. It is important to note, that only changes are returned by GET for performance reasons. Changes means, that if any of the "names" associated with an "id" changes, then all of the "names" for that "id" are returned. Also, when the Interval has passed, all "names" with a shorter or equal Interval will also be returned so they will all be in sync with the SIM.
{ "(id)": { "(name)": { "Name": "(datapath)", "Format": "(formatstring)", "UOM": "(requesteduom)", "Interval": (milliseconds) } , "(name2)": { "Name": "(datapath2)", "Format": "(formatstring2)", "UOM": "(requesteduom2)", "Interval": (milliseconds) } //optional ,... //followed with as many as you need } ,"(id2)": { "(name)": { "Name": "(datapath)", "Format": "(formatstring)", "UOM": "(requesteduom)", "Interval": (milliseconds) } //optional , "(name2)": { "Name": "(datapath2)", "Format": "(formatstring2)", "UOM": "(requesteduom2)", "Interval": (milliseconds) } //optional ,... //followed with as many as you need } ,... }
Formatter
.Data
.
Also, the call to POST will return this data as well. So, you want to parse the response body for both.
Failure to call GET within 10 seconds of the last call will assume the client has died and delete the session cache.
This should not be a problem as most practical applications will need to call GET multiple times per second.
To recover, the client can call POST again.
ReST
With ReST you do not call POST, because you can only specify one data path in the URL. Instead, you call GET with the data path appended to the URL after "/Data". For example: http://localhost/SIMRacingApps/Data/Car/REFERENCE/Description. Because of this, ReST does not perform as well as Subscribe/Publish for larger data sets. It also does not guarantee the data will be in sync between the calls to GET for multiple values. Therefore, it usefulness is degraded to when Subscribe/Publish is not needed, such as, one time or infrequent calls. By default, this returns a JSON string formatted "pretty" because I see it primarily being used from the browser ad-hoc. If the data returned refers to a structure, then the ValueFormatted may actually be a JSON string. For example: http://localhost/SIMRacingApps/Data/Car/REFERENCE, will return all the data available for that car in JSON format. You can specify the following parameters in the query string to change result returned.
Formatter
syntax.Data
for details).
What data paths are available?
The paths that are available is determined by searching the following classes for methods that returns a "Data
" object
and either takes no arguments or all of the arguments are strings. See each class for available paths.
Constructor and Description |
---|
Data()
Default Constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
destroy()
Gets called when the container destroys this object
|
void |
init(javax.servlet.ServletConfig config)
Initializes the servlet by getting the IP address and version information.
|
public void init(javax.servlet.ServletConfig config) throws javax.servlet.ServletException
init
in interface javax.servlet.Servlet
init
in class javax.servlet.GenericServlet
config
- The Servlet's configuration information.javax.servlet.ServletException
- Thrown so the server can log the error.public void destroy()
destroy
in interface javax.servlet.Servlet
destroy
in class javax.servlet.GenericServlet