Repository: struts-site Updated Branches: refs/heads/asf-site 740bd3f6d -> 77840af47
Updates production by Jenkins Project: http://git-wip-us.apache.org/repos/asf/struts-site/repo Commit: http://git-wip-us.apache.org/repos/asf/struts-site/commit/77840af4 Tree: http://git-wip-us.apache.org/repos/asf/struts-site/tree/77840af4 Diff: http://git-wip-us.apache.org/repos/asf/struts-site/diff/77840af4 Branch: refs/heads/asf-site Commit: 77840af477a698dde0edec39988c5646f3953c4f Parents: 740bd3f Author: jenkins <bui...@apache.org> Authored: Tue Sep 12 10:01:49 2017 +0000 Committer: jenkins <bui...@apache.org> Committed: Tue Sep 12 10:01:49 2017 +0000 ---------------------------------------------------------------------- content/plugins/index.html | 1 + content/plugins/json/index.html | 893 +++++++++++++++++++++++++++++++++++ 2 files changed, 894 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts-site/blob/77840af4/content/plugins/index.html ---------------------------------------------------------------------- diff --git a/content/plugins/index.html b/content/plugins/index.html index 0391bc5..866108f 100644 --- a/content/plugins/index.html +++ b/content/plugins/index.html @@ -128,6 +128,7 @@ <ul> <li><a href="convention/">Convention plugin</a></li> + <li><a href="json/">JSON plugin</a></li> <li><a href="junit/">JUnit plugin</a></li> </ul> http://git-wip-us.apache.org/repos/asf/struts-site/blob/77840af4/content/plugins/json/index.html ---------------------------------------------------------------------- diff --git a/content/plugins/json/index.html b/content/plugins/json/index.html new file mode 100644 index 0000000..84274cb --- /dev/null +++ b/content/plugins/json/index.html @@ -0,0 +1,893 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="Date-Revision-yyyymmdd" content="20140918"/> + <meta http-equiv="Content-Language" content="en"/> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + + <title>Convention plugin</title> + + <link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,400italic,600italic,700italic" rel="stylesheet" type="text/css"> + <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> + <link href="/css/main.css" rel="stylesheet"> + <link href="/css/custom.css" rel="stylesheet"> + <link href="/highlighter/github-theme.css" rel="stylesheet"> + + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <script type="text/javascript" src="/bootstrap/js/bootstrap.js"></script> + <script type="text/javascript" src="/js/community.js"></script> +</head> +<body> + +<a href="http://github.com/apache/struts" class="github-ribbon"> + <img style="position: absolute; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub"> +</a> + +<header> + <nav> + <div role="navigation" class="navbar navbar-default navbar-fixed-top"> + <div class="container"> + <div class="navbar-header"> + <button type="button" data-toggle="collapse" data-target="#struts-menu" class="navbar-toggle"> + Menu + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="/index.html" class="navbar-brand logo"><img src="/img/struts-logo.svg"></a> + </div> + <div id="struts-menu" class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li class="dropdown"> + <a data-toggle="dropdown" href="#" class="dropdown-toggle"> + Home<b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <li><a href="/index.html">Welcome</a></li> + <li><a href="/downloads.html">Downloads</a></li> + <li><a href="/announce.html">Announcements</a></li> + <li><a href="http://www.apache.org/licenses/">License</a></li> + <li><a href="http://apache.org/foundation/thanks.html">Thanks!</a></li> + <li><a href="http://apache.org/foundation/sponsorship.html">Sponsorship</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" href="#" class="dropdown-toggle"> + Support<b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <li><a href="/mail.html">User Mailing List</a></li> + <li><a href="https://issues.apache.org/jira/browse/WW">Issue Tracker</a></li> + <li><a href="/security.html">Reporting Security Issues</a></li> + <li class="divider"></li> + <li><a href="/maven/project-info.html">Project info</a></li> + <li><a href="/maven/struts2-core/dependencies.html">Struts Core dependencies</a></li> + <li><a href="/maven/struts2-plugins/modules.html">Plugin dependencies</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" href="#" class="dropdown-toggle"> + Documentation<b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <li><a href="/birdseye.html">Birds Eye</a></li> + <li><a href="/primer.html">Key Technologies</a></li> + <li><a href="/kickstart.html">Kickstart FAQ</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/WW/Home">Wiki</a></li> + <li class="divider"></li> + <li><a href="/getting-started/">Getting Started</a></li> + <li><a href="/security/">Security Guide</a></li> + <li><a href="/core-developers/">Core Developers Guide</a></li> + <li><a href="/plugins/">Plugins</a></li> + <li class="divider"></li> + <li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li> + <li><a href="/docs/plugins.html">Plugin APIs</a></li> + <li><a href="/docs/tag-reference.html">Tag reference</a></li> + <li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li> + <li class="divider"></li> + <li><a href="/docs/tutorials.html">Tutorials</a> - DEPRECATED</li> + <li><a href="/docs/faqs.html">FAQs</a> - DEPRECATED</li> + <li><a href="/docs/guides.html">Guides</a> - DEPRECATED</li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" href="#" class="dropdown-toggle"> + Contributing<b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <li><a href="/youatstruts.html">You at Struts</a></li> + <li><a href="/helping.html">How to Help FAQ</a></li> + <li><a href="/dev-mail.html">Development Lists</a></li> + <li class="divider"></li> + <li><a href="/submitting-patches.html">Submitting patches</a></li> + <li><a href="/builds.html">Source Code</a></li> + <li><a href="/coding-standards.html">Coding standards</a></li> + <li class="divider"></li> + <li><a href="/releases.html">Release Guidelines</a></li> + <li><a href="/bylaws.html">PMC Charter</a></li> + <li><a href="/volunteers.html">Volunteers</a></li> + <li><a href="https://git-wip-us.apache.org/repos/asf?p=struts.git">Source Repository</a></li> + </ul> + </li> + <li class="apache"><a href="http://www.apache.org/"><img src="/img/apache.png"></a></li> + </ul> + </div> + </div> + </div> + </nav> +</header> + + +<article class="container"> + <section class="col-md-12"> + <a href="../" title="back to Plugins"><< back to Plugins</a> + <a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/plugins/json/index.md" title="Edit this page on GitHub">Edit on GitHub</a> + <h1 class="no_toc" id="json-plugin">JSON Plugin</h1> + +<ul id="markdown-toc"> + <li><a href="#description" id="markdown-toc-description">Description</a></li> + <li><a href="#installation" id="markdown-toc-installation">Installation</a></li> + <li><a href="#customizing-serialization-and-deserialization" id="markdown-toc-customizing-serialization-and-deserialization">Customizing Serialization and Deserialization</a> <ul> + <li><a href="#excluding-properties" id="markdown-toc-excluding-properties">Excluding properties</a></li> + <li><a href="#including-properties" id="markdown-toc-including-properties">Including properties</a></li> + <li><a href="#root-object" id="markdown-toc-root-object">Root Object</a></li> + <li><a href="#wrapping" id="markdown-toc-wrapping">Wrapping</a></li> + <li><a href="#prefix" id="markdown-toc-prefix">Prefix</a></li> + <li><a href="#base-classes" id="markdown-toc-base-classes">Base Classes</a></li> + <li><a href="#enumerations" id="markdown-toc-enumerations">Enumerations</a></li> + <li><a href="#compressing-the-output" id="markdown-toc-compressing-the-output">Compressing the output</a></li> + <li><a href="#preventing-the-browser-from-caching-the-response" id="markdown-toc-preventing-the-browser-from-caching-the-response">Preventing the browser from caching the response</a></li> + <li><a href="#excluding-properties-with-null-values" id="markdown-toc-excluding-properties-with-null-values">Excluding properties with null values</a></li> + <li><a href="#status-and-error-code" id="markdown-toc-status-and-error-code">Status and Error code</a></li> + <li><a href="#jsonp" id="markdown-toc-jsonp">JSONP</a></li> + <li><a href="#content-type" id="markdown-toc-content-type">Content Type</a></li> + <li><a href="#encoding" id="markdown-toc-encoding">Encoding</a></li> + </ul> + </li> + <li><a href="#example" id="markdown-toc-example">Example</a> <ul> + <li><a href="#setup-action" id="markdown-toc-setup-action">Setup Action</a></li> + <li><a href="#write-the-mapping-for-the-action" id="markdown-toc-write-the-mapping-for-the-action">Write the mapping for the action</a></li> + <li><a href="#json-example-output" id="markdown-toc-json-example-output">JSON example output</a></li> + <li><a href="#accepting-json" id="markdown-toc-accepting-json">Accepting JSON</a></li> + </ul> + </li> + <li><a href="#json-rpc" id="markdown-toc-json-rpc">JSON RPC</a></li> + <li><a href="#proxied-objects" id="markdown-toc-proxied-objects">Proxied objects</a></li> +</ul> + +<h2 id="description">Description</h2> + +<p>The JSON plugin provides a <code class="highlighter-rouge">json</code> result type that serializes actions into JSON</p> + +<ol> + <li>The <code class="highlighter-rouge">content-type</code> must be <code class="highlighter-rouge">application/json</code></li> + <li>The JSON content must be well formed, see <a href="http://www.json.org">json.org</a> for grammar.</li> + <li>Action must have a public âsetterâ method for fields that must be populated.</li> + <li>Supported types for population are: Primitives (int,longâ¦String), Date, List, Map, Primitive Arrays, + other class (more on this later), and Array of Other class.</li> + <li>Any object in JSON, that is to be populated inside a list, or a map, will be of type Map (mapping from properties + to values), any whole number will be of type Long, any decimal number will be of type Double, and any array of type List.</li> +</ol> + +<p>Given this JSON string:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="w"> + </span><span class="nt">"doubleValue"</span><span class="p">:</span><span class="w"> </span><span class="mf">10.10</span><span class="p">,</span><span class="w"> + </span><span class="nt">"nestedBean"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> + </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mr Bean"</span><span class="w"> + </span><span class="p">},</span><span class="w"> + </span><span class="nt">"list"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"A"</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mf">20.20</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> + </span><span class="nt">"firstName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"El Zorro"</span><span class="w"> + </span><span class="p">}],</span><span class="w"> + </span><span class="nt">"array"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">20</span><span class="p">]</span><span class="w"> +</span><span class="p">}</span><span class="w"> +</span></code></pre> +</div> + +<p>The action must have a <code class="highlighter-rouge">setDoubleValue</code> method, taking either a <code class="highlighter-rouge">float</code> or a <code class="highlighter-rouge">double</code> argument (the interceptor will +convert the value to the right one). There must be a <code class="highlighter-rouge">setNestedBean</code> whose argument type can be any class, that has +a <code class="highlighter-rouge">setName</code> method taking as argument an <code class="highlighter-rouge">String</code>. There must be a <code class="highlighter-rouge">setList</code> method that takes a <code class="highlighter-rouge">List</code> as argument, +that list will contain: âAâ (<code class="highlighter-rouge">String</code>), 10 (<code class="highlighter-rouge">Long</code>), 20.20 (<code class="highlighter-rouge">Double</code>), Map (<code class="highlighter-rouge">firstName</code> -> <code class="highlighter-rouge">El Zorro</code>). +The <code class="highlighter-rouge">setArray</code> method can take as parameter either a <code class="highlighter-rouge">List</code>, or any numeric array.</p> + +<blockquote> + <p>So serialize your objects to JSON in javascript see <a href="http://json.org/json2.js">json2</a>.</p> +</blockquote> + +<p><code class="highlighter-rouge">root</code> attribute must be set on the <code class="highlighter-rouge">JSONInterceptor</code> when dealing with JSON array.</p> + +<p>This plugin also provides <em>AJAX Validation</em>.</p> + +<h2 id="installation">Installation</h2> + +<p>This plugin can be installed by copying the plugin jar into your applicationâs <code class="highlighter-rouge">/WEB-INF/lib</code> directory. No other +files need to be copied or created.</p> + +<p>To use maven, add this to your pom:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><dependencies></span> + ... + <span class="nt"><dependency></span> + <span class="nt"><groupId></span>org.apache.struts<span class="nt"></groupId></span> + <span class="nt"><artifactId></span>struts2-json-plugin<span class="nt"></artifactId></span> + <span class="nt"><version></span>STRUTS_VERSION<span class="nt"></version></span> + <span class="nt"></dependency></span> + ... +<span class="nt"></dependencies></span> +</code></pre> +</div> + +<h2 id="customizing-serialization-and-deserialization">Customizing Serialization and Deserialization</h2> + +<p>Use the JSON annotation to customize the serialization/deserialization process. Available JSON annotation fields:</p> + +<table> + <thead> + <tr> + <th>Name</th> + <th>Description</th> + <th>Default Value</th> + <th>Serialization</th> + <th>Deserialization</th> + </tr> + </thead> + <tbody> + <tr> + <td>name</td> + <td>Customize field name</td> + <td>empty</td> + <td>yes</td> + <td>no</td> + </tr> + <tr> + <td>serialize</td> + <td>Include in serialization</td> + <td>true</td> + <td>yes</td> + <td>no</td> + </tr> + <tr> + <td>deserialize</td> + <td>Include in deserialization</td> + <td>true</td> + <td>no</td> + <td>yes</td> + </tr> + <tr> + <td>format</td> + <td>Format used to format/parse a Date field</td> + <td>âyyyy-MM-ddâTâHH:mm:ssâ</td> + <td>yes</td> + <td>yes</td> + </tr> + </tbody> +</table> + +<h3 id="excluding-properties">Excluding properties</h3> + +<p>A comma-delimited list of regular expressions can be passed to the JSON Result and Interceptor, properties matching +any of these regular expressions will be ignored on the serialization process:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="c"><!-- Result fragment --></span> +<span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"excludeProperties"</span><span class="nt">></span> + login.password, + studentList.*.sin + <span class="nt"></param></span> +<span class="nt"></result></span> + +<span class="c"><!-- Interceptor fragment --></span> +<span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableSMD"</span><span class="nt">></span>true<span class="nt"></param></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"excludeProperties"</span><span class="nt">></span> + login.password, + studentList.*.sin + <span class="nt"></param></span> +<span class="nt"></interceptor-ref></span> +</code></pre> +</div> + +<h3 id="including-properties">Including properties</h3> + +<p>A comma-delimited list of regular expressions can be passed to the JSON Result to restrict which properties will +be serialized. ONLY properties matching any of these regular expressions will be included in the serialized output.</p> + +<blockquote> + <p>Exclude property expressions take precedence over include property expressions. That is, if you use include +and exclude property expressions on the same result, include property expressions will not be applied if an +exclude property expression matches a property first.</p> +</blockquote> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="c"><!-- Result fragment --></span> +<span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"includeProperties"</span><span class="nt">></span> + ^entries\[\d+\].clientNumber, + ^entries\[\d+\].scheduleNumber, + ^entries\[\d+\].createUserId + <span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="root-object">Root Object</h3> + +<p>Use the <code class="highlighter-rouge">root</code> attribute (OGNL expression) to specify the root object to be serialized.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"root"</span><span class="nt">></span> + person.job + <span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<p>The <code class="highlighter-rouge">root</code> attribute (OGNL expression) can also be used on the interceptor to specify the object that must be +populated, <strong>make sure this object is not null</strong>.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"root"</span><span class="nt">></span>bean1.bean2<span class="nt"></param></span> +<span class="nt"></interceptor-ref></span> +</code></pre> +</div> + +<h3 id="wrapping">Wrapping</h3> + +<p>For several reasons you might want to wrap the JSON output with some text, like wrapping with comments, adding a prefix, +or to use file uploads which require the result to be wrapped in a textarea. Use <code class="highlighter-rouge">wrapPrefix</code> to add content in +the beginning and <code class="highlighter-rouge">wrapPostfix</code> to add content at the end. This settings take precedence over <code class="highlighter-rouge">wrapWithComments</code> +and <code class="highlighter-rouge">prefix</code> which are deprecated from 0.34 on. Examples:</p> + +<ul> + <li>Wrap with comments: +```xml</li> +</ul> +<result type="json"> + <param name="wrapPrefix" />/* + <param name="wrapSuffix" />*/ +</result> +<div class="highlighter-rouge"><pre class="highlight"><code> +- Add a prefix: +```xml +<result type="json"> + <param name="wrapPrefix">{}&&</param> +</result> +</code></pre> +</div> + +<ul> + <li>Wrap for file upload: +```xml</li> +</ul> +<result type="json"> + <param name="wrapPrefix" /><![CDATA[<html><body><textarea>]]> + <param name="wrapSuffix" /><![CDATA[</textarea></body></html>]]> +</result> +<div class="highlighter-rouge"><pre class="highlight"><code> +### Wrap with Comments + +`wrapWithComments` is deprecated from 0.34, use `wrapPrefix` and `wrapSuffix` instead. + +> `wrapWithComments` can turn safe JSON text into dangerous text. For example, +> `"\*/ alert('XSS'); /\*"` +> Thanks to Douglas Crockford for the tip! Consider using **prefix** instead. + +If the serialized JSON is `{name: 'El Zorro'}`. Then the output will be: `{}&& ({name: 'El Zorro'})`. + +If the `wrapWithComments` (false by default) attribute is set to true, the generated JSON is wrapped with comments like: + +```json +/* { + "doubleVal": 10.10, + "nestedBean": { + "name": "Mr Bean" + }, + "list": ["A", 10, 20.20, { + "firstName": "El Zorro" + }], + "array": [10, 20] +} */ +</code></pre> +</div> +<p>To strip those comments use:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">responseObject</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="s2">"("</span><span class="o">+</span><span class="nx">data</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">"\/\*"</span><span class="p">)</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">lastIndexOf</span><span class="p">(</span><span class="s2">"\*\/"</span><span class="p">))</span><span class="o">+</span><span class="s2">")"</span><span class="p">);</span> +</code></pre> +</div> + +<h3 id="prefix">Prefix</h3> + +<p><code class="highlighter-rouge">prefix</code> is deprecated from 0.34, use <code class="highlighter-rouge">wrapPrefix</code> and <code class="highlighter-rouge">wrapSuffix</code> instead.</p> + +<p>If the parameter <code class="highlighter-rouge">prefix</code> is set to true, the generated JSON will be prefixed with <code class="highlighter-rouge"><span class="p">{}</span><span class="err">&&</span><span class="w"> </span></code>. This will help prevent +hijacking. See <a href="http://trac.dojotoolkit.org/ticket/6380">this Dojo Ticket</a> for details:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"prefix"</span><span class="nt">></span>true<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="base-classes">Base Classes</h3> + +<p>By default properties defined on base classes of the <code class="highlighter-rouge">root</code> object wonât be serialized, to serialize properties +in all base classes (up to Object) set <code class="highlighter-rouge">ignoreHierarchy</code> to false in the JSON result:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"ignoreHierarchy"</span><span class="nt">></span>false<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="enumerations">Enumerations</h3> + +<p>By default, an Enum is serialized as a <code class="highlighter-rouge">name=value</code> pair where <code class="highlighter-rouge">value = name()</code>.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">enum</span> <span class="n">AnEnum</span> <span class="o">{</span> + <span class="n">ValueA</span><span class="o">,</span> + <span class="n">ValueB</span> + <span class="o">}</span> +</code></pre> +</div> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="w"> </span><span class="s2">"myEnum"</span><span class="err">:</span><span class="s2">"ValueA"</span><span class="w"> +</span></code></pre> +</div> + +<p>Use the <code class="highlighter-rouge">enumAsBean</code> result parameter to serialize Enumâs as a bean with a special property <code class="highlighter-rouge">_name</code> with value <code class="highlighter-rouge">name()</code>. +All properties of the enum are also serialized.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">enum</span> <span class="n">AnEnum</span> <span class="o">{</span> + <span class="n">ValueA</span><span class="o">(</span><span class="s">"A"</span><span class="o">),</span> + <span class="n">ValueB</span><span class="o">(</span><span class="s">"B"</span><span class="o">);</span> + + <span class="kd">private</span> <span class="n">String</span> <span class="n">val</span><span class="o">;</span> + + <span class="kd">public</span> <span class="n">AnEnum</span><span class="o">(</span><span class="n">val</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">val</span> <span class="o">=</span> <span class="n">val</span><span class="o">;</span> + <span class="o">}</span> + <span class="kd">public</span> <span class="n">getVal</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">val</span><span class="o">;</span> + <span class="o">}</span> + <span class="o">}</span> +</code></pre> +</div> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="w"> </span><span class="err">myEnum:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ValueA"</span><span class="p">,</span><span class="w"> </span><span class="nt">"val"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="w"> </span><span class="p">}</span><span class="w"> +</span></code></pre> +</div> + +<p>Enable this parameter through <code class="highlighter-rouge">struts.xml</code>:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enumAsBean"</span><span class="nt">></span>true<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="compressing-the-output">Compressing the output</h3> + +<p>Set the <code class="highlighter-rouge">enableGZIP</code> attribute to true to gzip the generated json response. The request <strong>must</strong> include <code class="highlighter-rouge">gzip</code> +in the <code class="highlighter-rouge">Accept-Encoding</code> header for this to work.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableGZIP"</span><span class="nt">></span>true<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="preventing-the-browser-from-caching-the-response">Preventing the browser from caching the response</h3> + +<p>Set <code class="highlighter-rouge">noCache</code> to true (false by default) to set the following headers in the response:</p> + +<ul> + <li><code class="highlighter-rouge">Cache-Control: no-cache</code></li> + <li><code class="highlighter-rouge">Expires: 0</code></li> + <li><code class="highlighter-rouge">Pragma: No-cache</code></li> +</ul> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"noCache"</span><span class="nt">></span>true<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="excluding-properties-with-null-values">Excluding properties with null values</h3> + +<p>By default fields with null values are serialized like <code class="highlighter-rouge"><span class="p">{</span><span class="err">property_name:</span><span class="w"> </span><span class="err">null</span><span class="p">}</span></code>. This can be prevented +by setting <code class="highlighter-rouge">excludeNullProperties</code> to true.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"excludeNullProperties"</span><span class="nt">></span>true<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="status-and-error-code">Status and Error code</h3> + +<p>Use <code class="highlighter-rouge">statusCode</code> to set the status of the response:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"statusCode"</span><span class="nt">></span>304<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<p>And <code class="highlighter-rouge">errorCode</code> to send an error (the server might end up sending something to the client which is not the serialized JSON):</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="err"><result</span><span class="w"> </span><span class="err">type=</span><span class="s2">"json"</span><span class="err">></span><span class="w"> + </span><span class="err"><param</span><span class="w"> </span><span class="err">name=</span><span class="s2">"errorCode"</span><span class="err">></span><span class="mi">404</span><span class="err"></param></span><span class="w"> +</span><span class="err"></result></span><span class="w"> +</span></code></pre> +</div> + +<h3 id="jsonp">JSONP</h3> + +<p>To enable JSONP, set the parameter <code class="highlighter-rouge">callbackParameter</code> in either the JSON Result or the Interceptor. A parameter with +that name will be read from the request, and it value will be used as the JSONP function. Assuming that a request is +made with the parameter âcallbackâ=âexecâ:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"callbackParameter"</span><span class="nt">></span>callback<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<p>And that the serialized JSON is <code class="highlighter-rouge"><span class="p">{</span><span class="err">name:</span><span class="w"> </span><span class="err">'El</span><span class="w"> </span><span class="err">Zorro'</span><span class="p">}</span></code>. Then the output will be: <code class="highlighter-rouge">exec({name: 'El Zorro'})</code>.</p> + +<h3 id="content-type">Content Type</h3> + +<p>Content type will be set to <code class="highlighter-rouge">application/json-rpc</code> by default if SMD is being used, or <code class="highlighter-rouge">application/json</code> otherwise. +Sometimes it is necessary to set the content type to something else, like when uploading files with Dojo and YUI. +Use the <code class="highlighter-rouge">contentType</code> parameter in those cases.</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"contentType"</span><span class="nt">></span>text/html<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h3 id="encoding">Encoding</h3> + +<p>User can define encoding per result or base on default assigned to <code class="highlighter-rouge">struts.i18n.encoding</code>. To define encoding for +given result add encoding param as below:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"encoding"</span><span class="nt">></span>UTF-8<span class="nt"></param></span> +<span class="nt"></result></span> +</code></pre> +</div> + +<h2 id="example">Example</h2> + +<h3 id="setup-action">Setup Action</h3> + +<p>This simple action has some fields:</p> + +<p>Example:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.util.HashMap</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.util.Map</span><span class="o">;</span> + +<span class="kn">import</span> <span class="nn">com.opensymphony.xwork2.Action</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">JSONExample</span> <span class="o">{</span> + <span class="kd">private</span> <span class="n">String</span> <span class="n">field1</span> <span class="o">=</span> <span class="s">"str"</span><span class="o">;</span> + <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="n">ints</span> <span class="o">=</span> <span class="o">{</span><span class="mi">10</span><span class="o">,</span> <span class="mi">20</span><span class="o">};</span> + <span class="kd">private</span> <span class="n">Map</span> <span class="n">map</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">();</span> + <span class="kd">private</span> <span class="n">String</span> <span class="n">customName</span> <span class="o">=</span> <span class="s">"custom"</span><span class="o">;</span> + + <span class="c1">//'transient' fields are not serialized</span> + <span class="kd">private</span> <span class="kd">transient</span> <span class="n">String</span> <span class="n">field2</span><span class="o">;</span> + + <span class="c1">//fields without getter method are not serialized</span> + <span class="kd">private</span> <span class="n">String</span> <span class="n">field3</span><span class="o">;</span> + + <span class="kd">public</span> <span class="n">String</span> <span class="n">execute</span><span class="o">()</span> <span class="o">{</span> + <span class="n">map</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"John"</span><span class="o">,</span> <span class="s">"Galt"</span><span class="o">);</span> + <span class="k">return</span> <span class="n">Action</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="n">String</span> <span class="n">getField1</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">field1</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">void</span> <span class="n">setField1</span><span class="o">(</span><span class="n">String</span> <span class="n">field1</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">field1</span> <span class="o">=</span> <span class="n">field1</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="n">getInts</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">ints</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">void</span> <span class="n">setInts</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">ints</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">ints</span> <span class="o">=</span> <span class="n">ints</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="n">Map</span> <span class="n">getMap</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">map</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">void</span> <span class="n">setMap</span><span class="o">(</span><span class="n">Map</span> <span class="n">map</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">map</span> <span class="o">=</span> <span class="n">map</span><span class="o">;</span> + <span class="o">}</span> + + <span class="nd">@JSON</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="s">"newName"</span><span class="o">)</span> + <span class="kd">public</span> <span class="n">String</span> <span class="n">getCustomName</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">customName</span><span class="o">;</span> + <span class="o">}</span> +<span class="o">}</span> +</code></pre> +</div> + +<h3 id="write-the-mapping-for-the-action">Write the mapping for the action</h3> + +<ol> + <li>Add the map inside a package that extends <code class="highlighter-rouge">json-default</code></li> + <li>Add a result of type <code class="highlighter-rouge">json</code></li> +</ol> + +<p>Example with Convention Plugin Configuration:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.util.HashMap</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.util.Map</span><span class="o">;</span> + +<span class="kn">import</span> <span class="nn">com.opensymphony.xwork2.ActionSupport</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">org.apache.struts2.convention.annotation.Result</span><span class="o">;</span> + +<span class="nd">@Result</span><span class="o">(</span><span class="n">type</span> <span class="o">=</span> <span class="s">"json"</span><span class="o">)</span> +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">JSONExample</span> <span class="kd">extends</span> <span class="n">ActionSupport</span> <span class="o">{</span> +<span class="c1">// action code</span> +<span class="o">}</span> +</code></pre> +</div> + +<p>Example with XML Configuration:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="UTF-8" ?></span> +<span class="cp"><!DOCTYPE struts PUBLIC + "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" + "http://struts.apache.org/dtds/struts-2.0.dtd"></span> + +<span class="nt"><struts></span> + + <span class="nt"><package</span> <span class="na">name=</span><span class="s">"example"</span> <span class="na">extends=</span><span class="s">"json-default"</span><span class="nt">></span> + <span class="nt"><action</span> <span class="na">name=</span><span class="s">"JSONExample"</span> <span class="na">class=</span><span class="s">"example.JSONExample"</span><span class="nt">></span> + <span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">/></span> + <span class="nt"></action></span> + <span class="nt"></package></span> + +<span class="nt"></struts></span> +</code></pre> +</div> + +<h3 id="json-example-output">JSON example output</h3> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="w"> + </span><span class="nt">"field1"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"str"</span><span class="p">,</span><span class="w"> + </span><span class="nt">"ints"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">20</span><span class="p">],</span><span class="w"> + </span><span class="nt">"map"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> + </span><span class="nt">"John"</span><span class="p">:</span><span class="s2">"Galt"</span><span class="w"> + </span><span class="p">},</span><span class="w"> + </span><span class="nt">"newName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"custom"</span><span class="w"> +</span><span class="p">}</span><span class="w"> +</span></code></pre> +</div> + +<h3 id="accepting-json">Accepting JSON</h3> + +<p>Your actions can accept incoming JSON if they are in package which uses <code class="highlighter-rouge">json</code> interceptor or by adding reference +to it as follow:</p> + +<pre><code class="language-jaba">@InterceptorRef(value="json") +</code></pre> + +<p>By default <code class="highlighter-rouge">Content-Type</code> of value <code class="highlighter-rouge">application/json</code> is recognised to be used for de-serialisation +and <code class="highlighter-rouge">application/json-rpc</code> to execute SMD processing. You can override those settings be defining <code class="highlighter-rouge">jsonContentType</code> +and <code class="highlighter-rouge">jsonRpcContentType</code> params, see example:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"jsonContentType"</span><span class="nt">></span>text/json<span class="nt"></param></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"jsonRpcContentType"</span><span class="nt">></span>text/json-rpc<span class="nt"></param></span> +<span class="nt"></interceptor-ref></span> +</code></pre> +</div> + +<p>Please be aware that those are scoped params per stack, which means, once set it will be used by actions in scope of this stack.</p> + +<h2 id="json-rpc">JSON RPC</h2> + +<p>The json plugin can be used to execute action methods from javascript and return the output. This feature was developed +with Dojo in mind, so it uses <a href="http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book9">Simple Method Definition</a> +to advertise the remote service. Letâs work it out with an example(useless as most examples).</p> + +<p>First write the action:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="kn">package</span> <span class="n">smd</span><span class="o">;</span> + +<span class="kn">import</span> <span class="nn">com.googlecode.jsonplugin.annotations.SMDMethod</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">com.opensymphony.xwork2.Action</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SMDAction</span> <span class="o">{</span> + <span class="kd">public</span> <span class="n">String</span> <span class="n">smd</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">Action</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">;</span> + <span class="o">}</span> + + <span class="nd">@SMDMethod</span> + <span class="kd">public</span> <span class="n">Bean</span> <span class="n">doSomething</span><span class="o">(</span><span class="n">Bean</span> <span class="n">bean</span><span class="o">,</span> <span class="kt">int</span> <span class="n">quantity</span><span class="o">)</span> <span class="o">{</span> + <span class="n">bean</span><span class="o">.</span><span class="na">setPrice</span><span class="o">(</span><span class="n">quantity</span> <span class="o">*</span> <span class="mi">10</span><span class="o">);</span> + <span class="k">return</span> <span class="n">bean</span><span class="o">;</span> + <span class="o">}</span> +<span class="o">}</span> +</code></pre> +</div> + +<p>Methods that will be called remotely <strong>must</strong> be annotated with the <code class="highlighter-rouge">SMDMethod</code> annotation, for security reasons. +The method will take a bean object, modify its price and return it. The action can be annotated with the <code class="highlighter-rouge">SMD</code> annotation +to customize the generated SMD (more on that soon), and parameters can be annotated with <code class="highlighter-rouge">SMDMethodParameter</code>. As you +can see, we have a âdummyâ, <code class="highlighter-rouge">smd</code> method. This method will be used to generate the Simple Method Definition +(a definition of all the services provided by this class), using the <code class="highlighter-rouge">json</code> result.</p> + +<p>The bean class:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="kn">package</span> <span class="n">smd</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Bean</span> <span class="o">{</span> + <span class="kd">private</span> <span class="n">String</span> <span class="n">type</span><span class="o">;</span> + <span class="kd">private</span> <span class="kt">int</span> <span class="n">price</span><span class="o">;</span> + + <span class="kd">public</span> <span class="n">String</span> <span class="n">getType</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">type</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">void</span> <span class="n">setType</span><span class="o">(</span><span class="n">String</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">type</span> <span class="o">=</span> <span class="n">type</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">int</span> <span class="n">getPrice</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="n">price</span><span class="o">;</span> + <span class="o">}</span> + + <span class="kd">public</span> <span class="kt">void</span> <span class="n">setPrice</span><span class="o">(</span><span class="kt">int</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">price</span> <span class="o">=</span> <span class="n">price</span><span class="o">;</span> + <span class="o">}</span> + +<span class="o">}</span> +</code></pre> +</div> + +<p>The mapping:</p> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><package</span> <span class="na">name=</span><span class="s">"RPC"</span> <span class="na">namespace=</span><span class="s">"/nodecorate"</span> <span class="na">extends=</span><span class="s">"json-default"</span><span class="nt">></span> + <span class="nt"><action</span> <span class="na">name=</span><span class="s">"SMDAction"</span> <span class="na">class=</span><span class="s">"smd.SMDAction"</span> <span class="na">method=</span><span class="s">"smd"</span><span class="nt">></span> + <span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableSMD"</span><span class="nt">></span>true<span class="nt"></param></span> + <span class="nt"></interceptor-ref></span> + <span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableSMD"</span><span class="nt">></span>true<span class="nt"></param></span> + <span class="nt"></result></span> + <span class="nt"></action></span> +<span class="nt"></package></span> +</code></pre> +</div> + +<p>Nothing special here, except that <strong>both</strong> the interceptor and the result must be applied to the action, and <code class="highlighter-rouge">enableSMD</code> +must be enabled for both.</p> + +<p>Now the javascript code:</p> + +<pre><code class="language-jsp"><s:url id="smdUrl" namespace="/nodecorate" action="SMDAction" /> +<script type="text/javascript"> + //load dojo RPC + dojo.require("dojo.rpc.*"); + + //create service object(proxy) using SMD (generated by the json result) + var service = new dojo.rpc.JsonService("${smdUrl}"); + + //function called when remote method returns + var callback = function(bean) { + alert("Price for " + bean.type + " is " + bean.price); + }; + + //parameter + var bean = {type: "Mocca"}; + + //execute remote method + var defered = service.doSomething(bean, 5); + + //attach callback to defered object + defered.addCallback(callback); +</script> +</code></pre> + +<p>Dojoâs JsonService will make a request to the action to load the SMD, which will return a JSON object with the definition +of the available remote methods, using that information Dojo creates a âproxyâ for those methods. Because of the asynchronous +nature of the request, when the method is executed, a deferred object is returned, to which a callback function can be attached. +The callback function will receive as a parameter the object returned from your action. Thatâs it.</p> + +<h2 id="proxied-objects">Proxied objects</h2> + +<p>As annotations are not inherited in Java, some user might experience problems while trying to serialize objects that +are proxied. eg. when you have attached AOP interceptors to your action.</p> + +<p>In this situation, the plugin will not detect the annotations on methods in your action.</p> + +<p>To overcome this, set the <code class="highlighter-rouge">ignoreInterfaces</code> result parameter to false (true by default) to request that the plugin +inspects all interfaces and superclasses of the action for annotations on the actionâs methods.</p> + +<blockquote> + <p>This parameter should only be set to false if your action could be a proxy as there is a performance cost caused +by recursion through the interfaces.</p> +</blockquote> + +<div class="highlighter-rouge"><pre class="highlight"><code><span class="nt"><action</span> <span class="na">name=</span><span class="s">"contact"</span> <span class="na">class=</span><span class="s">"package.ContactAction"</span> <span class="na">method=</span><span class="s">"smd"</span><span class="nt">></span> + <span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableSMD"</span><span class="nt">></span>true<span class="nt"></param></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"ignoreSMDMethodInterfaces"</span><span class="nt">></span>false<span class="nt"></param></span> + <span class="nt"></interceptor-ref></span> + <span class="nt"><result</span> <span class="na">type=</span><span class="s">"json"</span><span class="nt">></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"enableSMD"</span><span class="nt">></span>true<span class="nt"></param></span> + <span class="nt"><param</span> <span class="na">name=</span><span class="s">"ignoreInterfaces"</span><span class="nt">></span>false<span class="nt"></param></span> + <span class="nt"></result></span> + <span class="nt"><interceptor-ref</span> <span class="na">name=</span><span class="s">"default"</span><span class="nt">/></span> +<span class="nt"></action></span> +</code></pre> +</div> + + </section> +</article> + + +<footer class="container"> + <div class="col-md-12"> + Copyright © 2000-2016 <a href="http://www.apache.org/">The Apache Software Foundation </a>. + All Rights Reserved. + </div> + <div class="col-md-12"> + Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are + trademarks of The Apache Software Foundation. + </div> + <div class="col-md-12">Logo and website design donated by <a href="https://softwaremill.com/">SoftwareMill</a>.</div> +</footer> + +<script>!function (d, s, id) { + var js, fjs = d.getElementsByTagName(s)[0]; + if (!d.getElementById(id)) { + js = d.createElement(s); + js.id = id; + js.src = "//platform.twitter.com/widgets.js"; + fjs.parentNode.insertBefore(js, fjs); + } +}(document, "script", "twitter-wjs");</script> +<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"></script> + +<div id="fb-root"></div> + +<script>(function (d, s, id) { + var js, fjs = d.getElementsByTagName(s)[0]; + if (d.getElementById(id)) return; + js = d.createElement(s); + js.id = id; + js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1"; + fjs.parentNode.insertBefore(js, fjs); +}(document, 'script', 'facebook-jssdk'));</script> + + +<script> +$(function() { + return $("h2, h3, h4, h5, h6").each(function(i, el) { + var $el, id; + $el = $(el); + id = $el.attr('id'); + if (id) { + $el.removeAttr('id'); + return $el.before($("<a />").addClass('anchor').attr('name', id)); + } + }); +}); +</script> + +</body> +</html>