JSON Services using Struts2

I’ve implemented some of my front-end using javascript (jquery) and needed to expose some JSON services to enable this.  As I’m using Struts2 as my MVC framework.  There is a Struts2-jQuery tag library you can use.  However, this post is just about exposing the Struts2 action as a JSON service so that it can be used by straight jQuery (or whatever javascript library you choose to use).

The jQuery to call the service

var timestamp = new Date().getTime();

var cuurl = “/events_json.action?ts=” + timestamp;

var data = {

action: “search”,

start: startAt,

max: maxResults,

activity: activitySearchFor,

area: area,

country: country,

state: state,

town: town

};

$.post(cuurl,

data,

function(response) {

eventUtil.handleResponse(response);

},

“json”

);

Note –  ?ts=” + timestamp to overcome potential response caching issues.

The struts.xml definition

<action name=“events_json” class=“eventsAction” method=“json” >

</action>

Note 1 – no results are defined

Note 2 – I’m using Spring to define my classes

My Struts action class

public class EventsAction extends FFFFBaseAction

implements ServletResponseAware,

ParameterAware{

Implement the ServletResponseAware and ParameterAware interfaces to be able to access the response object and the parameters.

private static final String JSON_ACTION_PARAM = “action”;

private static final String JSON_STARTAT_PARAM = “start”;

private static final String JSON_MAXRESULTS_PARAM = “max”;

private static final String JSON_ACTIVITY_PARAM = “activity”;

private static final String JSON_AREA_PARAM = “area”;

private static final String JSON_COUNTRY_PARAM = “country”;

private static final String JSON_STATE_PARAM = “state”;

private static final String JSON_TOWN_PARAM = “town”;

Parameter name values

private HttpServletResponse response;

private Map parameters;

@Override

public void setServletResponse(HttpServletResponse response) {

this.response = response;

}

@Override

public void setParameters(Map parameters) {

this.parameters = parameters;

}

The json method.  This is a common entry point for multiple json services

public String json() {

String toRet = null;

getValuesFromSession();

String[] actions = (String[])parameters.get(JSON_ACTION_PARAM);

String action = getStringValFromParam(actions);

logger.debug(“action is ” + action);

String jsonString = “”;

// common object I am using to wrap the data my services return

JsonResult jResult = null;

// I’m using this method as a common entry point for many json services

if (“search”.equals(action)) {

jResult = search();

} else if (“next”.equals(action)) {

jResult = next();

} else if (“previous”.equals(action)) {

jResult = previous();

} else {

logger.error(“json method called but action not set or not recognised – action is” + action);

jResult = new JsonResult();

jResult.setError(true);

jResult.setErrorMessage(“Sorry, there as an unexpected problem”);

}

try {

// I am using the google gson library to convert from java beans

// to a json string

Gson gson = new Gson();

jsonString = gson.toJson(jResult);

//logger.debug(“A json string ” + jsonString);

} catch (Exception e) {

logger.error(“gson can’t cope with the results”, e);

// try again, to return error

jResult = new JsonResult();

jResult.setError(true);

jResult.setErrorMessage(“Sorry, there as an unexpected problem”);

try {

Gson gson = new Gson();

jsonString = gson.toJson(jResult);

} catch (Exception eAgain) {

logger.error(“gson can’t cope with the results again”, eAgain);

}

}

try {

response.setCharacterEncoding(“UTF-8”); // to deal with special characters

PrintWriter pw = response.getWriter();

// this response.printwriter.write call is where the json string

// is returned to the calling javascript

pw.write(jsonString);

} catch (IOException ioe) {

logger.error(“there was IOException in json method”, ioe);

}

// toRet is null – we can return null.  There are no results

// defined in the xml definition

return toRet;

}

The search method.  This contains the logic for this service

private JsonResult search() {

// the object I will return and then convert to a json string

JsonResult toRet = new JsonResult();

toRet.setError(false);

logger.info(“In search”);

try {

// getting the values that the javascript set as parameters

String[] startAtStrs = (String[])parameters.get(JSON_STARTAT_PARAM);

String startAtStr = getStringValFromParam(startAtStrs);

String[] maxResultsStrs = (String[])parameters.get(JSON_MAXRESULTS_PARAM);

String maxResultsStr = getStringValFromParam(maxResultsStrs);

String[] activityStrs = (String[])parameters.get(JSON_ACTIVITY_PARAM);

String activityStr = getStringValFromParam(activityStrs);

String[] areaStrs = (String[])parameters.get(JSON_AREA_PARAM);

String areaStr = getStringValFromParam(areaStrs);

String[] countryStrs = (String[])parameters.get(JSON_COUNTRY_PARAM);

String countryStr = getStringValFromParam(countryStrs);

String[] stateStrs = (String[])parameters.get(JSON_STATE_PARAM);

String stateStr = getStringValFromParam(stateStrs);

String[] townStrs = (String[])parameters.get(JSON_TOWN_PARAM);

String townStr = getStringValFromParam(townStrs);

…..

// wrapper for our results

EventSearchResult eventSearchResult = new EventSearchResult();

List<EventActivityResult> eaResults = new ArrayList<EventActivityResult>();

eventSearchResult.setEventActivityResults(eaResults);

…..

// Access the database to get some data

List<Event> events = null;

events = eventService.search(activityId, area, meFFFFEntity, countryStr, stateStr, townStr, eventOrderBy, ascDesc, hibernateStartAt, maxResults, ffffEntityIdsNotWanted);

// we don’t want to convert the hibernate entities to json because

// A – that would mean sending more data than we need to – and

// B – lazy loaded hibernate proxies don’t like (will throw exceptions)

// being converted to json

// so here we transform from hibernate entities to java beans

// that contain just the info the front end needs

// so gson doesn’t have to parse a hibernate proxy

List<JsonEvent> jsonEvents = JsonEventTransform.toJsonShortForm(events);

EventActivityResult eaResult = new EventActivityResult();

//ueResult.setEvents(events);

eaResult.setJsonEvents(jsonEvents);

eaResult.setMaxResults(maxResults);

eaResult.setNumberOfResults(count);

eaResult.setStartAt(startAt);

eaResult.setShowingDisplayString(SearchUtil.createShowingDisplayString(hibernateStartAt, maxResults, count));

eaResult.setActivityId(activityId);

eaResult.setActivityName(activityName);

eaResults.add(eaResult);

…..

toRet.setResult(eventSearchResult);

} catch (Exception e) {

logger.error(“there was a exception getting events when user searched ” + meFFFFEntity, e);

toRet.setError(true);

// TODO – where get error message from?

toRet.setErrorMessage(“Sorry, there was an unexpected problem.”);

}

return toRet;

}

Common class I use to wrap data to be converted to json

public class JsonResult {

private boolean error;

private String errorMessage;

private Object result;

// constructor and getter and setter methods

}

Java bean for the event entity that can be converted to json

public class JsonEvent implements Serializable {

private Integer id;

private String title;

private String shortDesc;

private String description;

private boolean cancelled;

private String startDate;

private String country;

private String state;

private String town;

private String formattedAddress;

private JsonFFFFEntity owner;

private List<JsonActivity> activities;

// constructor and getter and setter methods

}

To transform from hibernate entity to java bean

public class JsonEventTransform {

public static List<JsonEvent> toJsonShortForm(List<Event> events) {

// method body

}

Advertisements
This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

One Response to JSON Services using Struts2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s