{"id":118,"date":"2009-07-12T12:46:02","date_gmt":"2009-07-12T19:46:02","guid":{"rendered":"http:\/\/www.zulutown.com\/blog\/?p=118"},"modified":"2009-07-13T00:50:00","modified_gmt":"2009-07-13T07:50:00","slug":"ajax-dynamic-content-with-struts2-jquery-and-json-plugin","status":"publish","type":"post","link":"https:\/\/www.zulutown.com\/blog\/2009\/07\/12\/ajax-dynamic-content-with-struts2-jquery-and-json-plugin\/","title":{"rendered":"Ajax Dynamic Content with Struts2, JQuery and JSON plugin"},"content":{"rendered":"<p>This guide explains how to create a simple web application that dynamically populates a page through AJAX, using both Struts2 and the JSON features of JQuery.<br \/>\n\ufeffFirst of all it&#8217;s required the Json Plugin (available at <a href=\"http:\/\/jsonplugin.googlecode.com\" target=\"_blank\">http:\/\/jsonplugin.googlecode.com<\/a>) that should be placed in the <code>\/WEB-INF\/lib\/<\/code> directory (where obviously are placed all the Struts2 jar as explained in other tutorials of this site).<\/p>\n<p>The plugin adds (through its struts-plugin.xml) a new result type defined this way:<\/p>\n<pre>&lt;package name=\"json-default\" extends=\"struts-default\"&gt;\r\n &lt;result-types&gt;\r\n  &lt;result-type name=\"json\" class=\"com.googlecode.jsonplugin.JSONResult\"\/&gt;\r\n &lt;\/result-types&gt;\r\n ...\r\n&lt;\/package&gt;<\/pre>\n<p>Since it&#8217;s defined in the <code>json-default<\/code> package, in order to use that result inside custom action mappings, there are two choices:<\/p>\n<ul>\n<li> the packages containing actions with <code>json<\/code> result-type have to extend the package <code>json-default<\/code> and not, as usual, the <code>struts-default<\/code> package<\/li>\n<li>in the packages where <code>json<\/code> result-type is used, it&#8217;s to possible to add the previous <code>&lt;result-types&gt;...&lt;\/result-types&gt;<\/code> lines that simply refers to a class contained in the json plugin <code>.jar<\/code> added to the application.<\/li>\n<\/ul>\n<p>It&#8217;s now possible to define action mappings using <code>json<\/code> as result type, like the following one:<\/p>\n<pre>&lt;package name=\"testPackage\" extends=\"json-default\" namespace=\"\/test\"&gt;\r\n &lt;action name=\"giveMeJsonData\" class=\"testAction\" method=\"giveMe\"&gt;\r\n  &lt;result type=\"json\"&gt;\r\n   &lt;param name=\"root\"&gt;jsonData&lt;\/param&gt;\r\n  &lt;\/result&gt;\r\n &lt;\/action&gt;\r\n...\r\n&lt;\/package&gt;<\/pre>\n<p>The above definition states that the url <code>\/test\/giveMeJsonData.action<\/code> will cause the execution of the method <code>public String giveMe()<\/code> defined inside the class <code>testAction<\/code> (in this case it&#8217;s a Spring managed bean, but it can be even a qualified name of a Struts2 action class, obviously extending ActionSupport class).<\/p>\n<p>The result of that action (with a <code>SUCCESS<\/code> result code) is the json data structure stored in the <code>jsonData<\/code> property of the action class, and so available through its getter <code>getJsonData()<\/code>.<\/p>\n<p>An example of the behavior for <code>giveMe()<\/code> method:<\/p>\n<pre>public String giveMe() {\r\n jsonData = new LinkedHashMap&lt;String, Object&gt;();\r\n jsonData.put(\"shoppingCartId\", getCartId());\r\n jsonData.put(\"datetime\", new Date());\r\n Set&lt;Map&lt;String, Object&gt;&gt; items = new HashSet&lt;Map&lt;String, Object&gt;&gt;();\r\n for (Item item : businessMethod.findItemsForCart(getCartId())) {\r\n  HashMap&lt;String, Object&gt; itemMap = new HashMap&lt;String, Object&gt;();\r\n  itemMap.put(\"id\", item.getId());\r\n  itemMap.put(\"quantity\", item.getQuantity());\r\n  itemMap.put(\"price\", item.getPrice);\r\n  items.add(itemMap);\r\n }\r\n jsonData.put(\"items\", items);\r\n return SUCCESS;\r\n}<\/pre>\n<p>The final step is to use JQuery to call (on a specific event) through AJAX the URL where the action has been defined, and obviously to use the returned data to dynamically populate the page HTML.<\/p>\n<pre>function testingJsonAndAjax(cartId) {\r\n $.getJSON(\r\n  \/test\/giveMeJsonData.action ,\r\n  {\r\n   cartId: cartId\r\n  },\r\n  function(json) {\r\n   $('#cartId').html(json.shoppingCartId);\r\n   $('#cartCreation').html(json.datetime);\r\n   itemsHtml = \"&lt;table&gt;\";\r\n   for (i in json.items) {\r\n    itemsHtml += \u201c&lt;tr&gt;\u201d;\r\n    itemsHtml += \u201c&lt;td&gt;\u201d + json.items[i].id + \u201c&lt;\/td&gt;\u201d;\r\n    itemsHtml += \u201c&lt;td&gt;\u201d + json.items[i].quantity + \u201c&lt;\/td&gt;\u201d;\r\n    itemsHtml += \u201c&lt;td&gt;\u201d + json.items[i].price + \u201c&lt;\/td&gt;\u201d;\r\n    itemsHtml += \u201c&lt;\/tr&gt;\u201d;\r\n   }\r\n   itemsHtml += \u201c&lt;\/table&gt;\u201d;\r\n   $('#cartItems').html(itemsHtml);\r\n  }\r\n );\r\n return false;\r\n}<\/pre>\n<p>A sample HTML would look like this<\/p>\n<pre>Cart 32233 &lt;a href=\u201d#\u201d onclick=\"return testingJsonAndAjax(32233)&gt;Refresh&lt;\/a&gt; &lt;br \/&gt;\r\nCart 82382 &lt;a href=\u201d#\u201d onclick=\"return testingJsonAndAjax(82382)&gt;Refresh&lt;\/a&gt; &lt;br \/&gt;\r\n\r\n&lt;div id=\u201dcartId\u201d&gt;JQuery will replace this text with the Cart Id returned by the json action&lt;\/div&gt;\r\n&lt;div id=\u201dcartCreation\u201d&gt;JQuery will replace this text with the Cart creation date returned by the json action&lt;\/div&gt;\r\n&lt;div id=\u201dcartItems\u201d&gt;Jquery wil replace this text with a HTML table containg all the items of the selected cart&lt;\/div&gt;<\/pre>\n<p>The <code>id<\/code> will be used by the JQuery selector to determine in which of them the data returned by the json action will be written in.<\/p>\n<p>I hope this tutorial has been useful for a simple introduction to AJAX and JSON using JQuery and Struts2.<\/p>\n<p><strong>EDIT 1:<\/strong> on the Struts User Mailing List, <a href=\"http:\/\/www.manning.com\/wannemacher\">Wes Wannemacher<\/a> suggested that it would be better to directly put the item object inside the root object returned through JSON.<\/p>\n<p>This is absolutely right and would lead to cleaner code. But I didn&#8217;t used that technique for a security reason, i.e. if the Item object is a JPA entity, it may contain some properties that is better not to show to the end users. In the case of a User entity, it would be no good to return in the json data its hashed password.<\/p>\n<p>So I created that <em>ugly<\/em> workaround, defining some HashMaps and putting there just the specific properties I wish to return in the Json result (and maybe this will save too some HTTP traffic \ud83d\ude42 )<\/p>\n<p><strong>EDIT 2:<\/strong> on the Struts User Mailing List, Nils-Helge Garli Hegvik suggested that it&#8217;s even possible to use the &#8220;includeProperties&#8221; or &#8220;excludeProperties&#8221; parameters (as described <a href=\"http:\/\/cwiki.apache.org\/S2PLUGINS\/json-plugin.html\">here<\/a>) in the result configuration to simply return some objects and the JSON plugin will do the trick of filtering just the specific properties to show.<\/p>\n<div id=\"_mcePaste\" style=\"overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;\">in the packages where \u201cjson\u201d result-type is used, it&#8217;s to possibile to add the previous &amp;lt;result-types&amp;gt;&#8230;&amp;lt;\/result-types&amp;gt; lines that simply refers to a class contained in the .jar added to the application (contained in the json-plugin jar).<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This guide explains how to create a simple web application that dynamically populates a page through AJAX, using both Struts2 and the JSON features of JQuery. \ufeffFirst of all it&#8217;s required the Json Plugin (available at http:\/\/jsonplugin.googlecode.com) that should be &hellip; <a href=\"https:\/\/www.zulutown.com\/blog\/2009\/07\/12\/ajax-dynamic-content-with-struts2-jquery-and-json-plugin\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[133,11,134,9],"tags":[142,175,143,141,168,176,19,137,140,139,135,138,136,167],"class_list":["post-118","post","type-post","status-publish","format-standard","hentry","category-ajax","category-java-ee","category-jquery","category-struts2","tag-actionsupport","tag-ajax","tag-dynamically","tag-jar","tag-java-ee","tag-jquery","tag-json","tag-json-default","tag-jsonplugin","tag-jsonresult","tag-plugin","tag-struts-default","tag-struts-plugin-xml","tag-struts2"],"_links":{"self":[{"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/posts\/118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/comments?post=118"}],"version-history":[{"count":14,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/posts\/118\/revisions"}],"predecessor-version":[{"id":127,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/posts\/118\/revisions\/127"}],"wp:attachment":[{"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/media?parent=118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/categories?post=118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zulutown.com\/blog\/wp-json\/wp\/v2\/tags?post=118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}