You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by cn...@apache.org on 2016/01/29 13:55:01 UTC

[1/4] struts git commit: WW-4599: backport JSONActionRedirectResult to struts 2.3

Repository: struts
Updated Branches:
  refs/heads/support-2-3 15c79e139 -> 2a6acabe5


WW-4599: backport JSONActionRedirectResult to struts 2.3


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/69bc2947
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/69bc2947
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/69bc2947

Branch: refs/heads/support-2-3
Commit: 69bc2947c17188bda2502a5bfe1c19e427583581
Parents: 15c79e1
Author: cnenning <cn...@apache.org>
Authored: Mon Jan 11 14:36:32 2016 +0100
Committer: cnenning <cn...@apache.org>
Committed: Fri Jan 29 13:53:31 2016 +0100

----------------------------------------------------------------------
 .../validation/AjaxFormSubmitAction.java        | 152 ++++++++++++++++
 .../validation/AjaxFormSubmitSuccessAction.java |   7 +
 .../src/main/resources/struts-validation.xml    |  13 ++
 .../ajaxErrorContainers/actionerror.ftl         |  46 +++++
 .../ajaxErrorContainers/controlfooter.ftl       |  39 ++++
 .../ajaxErrorContainers/controlheader-core.ftl  |  80 +++++++++
 .../ajaxErrorContainers/theme.properties        |  21 +++
 .../src/main/webapp/WEB-INF/decorators/main.jsp |   1 -
 .../WEB-INF/validation/ajaxFormSubmit.jsp       | 177 +++++++++++++++++++
 .../validation/ajaxFormSubmitSuccess.jsp        |  17 ++
 .../main/webapp/WEB-INF/validation/index.jsp    |   2 +
 .../struts2/json/JSONActionRedirectResult.java  |  71 ++++++++
 .../struts2/json/JSONValidationInterceptor.java |   6 +-
 .../json/src/main/resources/struts-plugin.xml   |   1 +
 .../json/JSONActionRedirectResultTest.java      | 105 +++++++++++
 15 files changed, 735 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
new file mode 100644
index 0000000..b179370
--- /dev/null
+++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
@@ -0,0 +1,152 @@
+package org.apache.struts2.showcase.validation;
+
+import java.sql.Date;
+
+import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.EmailValidator;
+import com.opensymphony.xwork2.validator.annotations.FieldExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.UrlValidator;
+
+/**
+ * <!-- START SNIPPET: ajaxFormSubmit -->
+ */
+/**
+ * Example Action that shows how forms can be validated and submitted via AJAX
+ * only. Form-submit-and-page-reload functionality of browsers is not used for
+ * this action.
+ * <p>Some things to note:
+ * <ul>
+ *   <li>Depends on <code>json-plugin</code>.</li>
+ *   <li>Requires <code>jsonValidationInterceptor</code> to be on stack.</li>
+ *   <li>Uses a special json redirect result type.</li>
+ *   <li>Uses http parameters <code>struts.enableJSONValidation=true</code> and <code>struts.validateOnly=false</code>.</li>
+ *   <li>Uses a customized theme to make sure html elements required as error containers are always present and easily selectable in JS.</li>
+ *   <li>Uses some custom JS code depending on jQuery to issue AJAX request and to render errors in html.</li>
+ *   <li>Shows visual feedback while waiting for AJAX response.</li>
+ * </ul>
+ * </p>
+ *
+ */
+public class AjaxFormSubmitAction extends AbstractValidationActionSupport {
+
+    private String requiredValidatorField = null;
+    private String requiredStringValidatorField = null;
+    private Integer integerValidatorField = null;
+    private Date dateValidatorField = null;
+    private String emailValidatorField = null;
+    private String urlValidatorField = null;
+    private String stringLengthValidatorField = null;
+    private String regexValidatorField = null;
+    private String fieldExpressionValidatorField = null;
+
+    @Override
+    public void validate() {
+        if (hasFieldErrors()) {
+            addActionError("Errors present!");
+        }
+    }
+
+    public Date getDateValidatorField() {
+        return dateValidatorField;
+    }
+
+    @DateRangeFieldValidator(
+        min="01/01/1990", 
+        max="01/01/2000", 
+        message="must be a min 01-01-1990 max 01-01-2000 if supplied")
+    public void setDateValidatorField(Date dateValidatorField) {
+        this.dateValidatorField = dateValidatorField;
+    }
+
+    public String getEmailValidatorField() {
+        return emailValidatorField;
+    }
+
+    @EmailValidator(message="must be a valid email if supplied")
+    public void setEmailValidatorField(String emailValidatorField) {
+        this.emailValidatorField = emailValidatorField;
+    }
+
+    public Integer getIntegerValidatorField() {
+        return integerValidatorField;
+    }
+
+    @IntRangeFieldValidator(min="1", max="10", message="must be integer min 1 max 10 if supplied")
+    public void setIntegerValidatorField(Integer integerValidatorField) {
+        this.integerValidatorField = integerValidatorField;
+    }
+
+    public String getRegexValidatorField() {
+        return regexValidatorField;
+    }
+
+    @RegexFieldValidator(
+        regex="[^<>]+", 
+        message="regexValidatorField must match a regexp (.*\\.txt) if specified")
+    public void setRegexValidatorField(String regexValidatorField) {
+        this.regexValidatorField = regexValidatorField;
+    }
+
+    public String getRequiredStringValidatorField() {
+        return requiredStringValidatorField;
+    }
+
+    @RequiredStringValidator(trim=true, message="required and must be string")
+    public void setRequiredStringValidatorField(String requiredStringValidatorField) {
+        this.requiredStringValidatorField = requiredStringValidatorField;
+    }
+
+    public String getRequiredValidatorField() {
+        return requiredValidatorField;
+    }
+
+    @RequiredFieldValidator(message="required")
+    public void setRequiredValidatorField(String requiredValidatorField) {
+        this.requiredValidatorField = requiredValidatorField;
+    }
+
+    public String getStringLengthValidatorField() {
+        return stringLengthValidatorField;
+    }
+
+    @StringLengthFieldValidator(
+        minLength="2", 
+        maxLength="4", 
+        trim=true, 
+        message="must be a String of a specific greater than 1 less than 5 if specified")
+    public void setStringLengthValidatorField(String stringLengthValidatorField) {
+        this.stringLengthValidatorField = stringLengthValidatorField;
+    }
+
+    public String getFieldExpressionValidatorField() {
+        return fieldExpressionValidatorField;
+    }
+
+	@FieldExpressionValidator(
+        expression = "(fieldExpressionValidatorField == requiredValidatorField)", 
+        message = "must be the same as the Required Validator Field if specified")
+    public void setFieldExpressionValidatorField(
+            String fieldExpressionValidatorField) {
+        this.fieldExpressionValidatorField = fieldExpressionValidatorField;
+    }
+
+    public String getUrlValidatorField() {
+        return urlValidatorField;
+    }
+
+    @UrlValidator(message="must be a valid url if supplied")
+    public void setUrlValidatorField(String urlValidatorField) {
+        this.urlValidatorField = urlValidatorField;
+    }
+}
+
+/**
+ * <!-- END SNIPPET: ajaxFormSubmit -->
+ */
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitSuccessAction.java
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitSuccessAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitSuccessAction.java
new file mode 100644
index 0000000..6eca3fc
--- /dev/null
+++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitSuccessAction.java
@@ -0,0 +1,7 @@
+package org.apache.struts2.showcase.validation;
+
+public class AjaxFormSubmitSuccessAction {
+	public String execute() {
+		return "success";
+	}
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/resources/struts-validation.xml
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/resources/struts-validation.xml b/apps/showcase/src/main/resources/struts-validation.xml
index ee40dc9..fc59210 100755
--- a/apps/showcase/src/main/resources/struts-validation.xml
+++ b/apps/showcase/src/main/resources/struts-validation.xml
@@ -29,6 +29,19 @@
             <result name="input">quiz-ajax.jsp</result>
             <result>quiz-success.jsp</result>
         </action>
+
+		<!-- =========================================== -->
+		<!-- === ajax form submit                    === -->
+		<!-- =========================================== -->
+		<action name="ajaxFormSubmit" class="org.apache.struts2.showcase.validation.AjaxFormSubmitAction">
+			<interceptor-ref name="jsonValidationWorkflowStack" />
+			<result name="input">/WEB-INF/validation/ajaxFormSubmit.jsp</result>
+			<result type="jsonActionRedirect">ajaxFormSubmitSuccess</result>
+		</action>
+		<action name="ajaxFormSubmitSuccess" class="org.apache.struts2.showcase.validation.AjaxFormSubmitSuccessAction">
+			<result>/WEB-INF/validation/ajaxFormSubmitSuccess.jsp</result>
+		</action>
+		
 	</package>
 
 

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/resources/template/ajaxErrorContainers/actionerror.ftl
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/resources/template/ajaxErrorContainers/actionerror.ftl b/apps/showcase/src/main/resources/template/ajaxErrorContainers/actionerror.ftl
new file mode 100644
index 0000000..3f7d8ab
--- /dev/null
+++ b/apps/showcase/src/main/resources/template/ajaxErrorContainers/actionerror.ftl
@@ -0,0 +1,46 @@
+<#--
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+<#--
+    Make sure element is always present. To be filled later via JS.
+-->
+<ul<#rt/>
+<#if parameters.id??>
+ id="${parameters.id?html}"<#rt/>
+</#if>            
+<#if parameters.cssClass??>
+ class="${parameters.cssClass?html}"<#rt/>
+<#else>
+ class="errorMessage"<#rt/>
+</#if>
+<#if parameters.cssStyle??>
+ style="${parameters.cssStyle?html}"<#rt/>
+</#if>
+>
+<#if (actionErrors?? && actionErrors?size > 0)>
+	<#list actionErrors as error>
+		<#if error??>
+            <li><span><#if parameters.escape>${error!?html}<#else>${error!}</#if></span><#rt/></li><#rt/>
+        </#if>
+	</#list>
+</#if>
+</ul>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlfooter.ftl
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlfooter.ftl b/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlfooter.ftl
new file mode 100644
index 0000000..7f95111
--- /dev/null
+++ b/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlfooter.ftl
@@ -0,0 +1,39 @@
+<#--
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+${parameters.after!}<#t/>
+    </td><#lt/>
+</tr>
+<#if (parameters.errorposition!"top") == 'bottom'>
+<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>
+<#if hasFieldErrors>
+<tr errorFor="${parameters.id}">
+    <td class="tdErrorMessage" colspan="2"><#rt/>
+        <#if hasFieldErrors>
+            <#list fieldErrors[parameters.name] as error>
+                <div class="errorMessage">${error?html}</div><#t/>
+            </#list>
+        </#if>
+    </td><#lt/>
+</tr>
+</#if>
+</#if>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlheader-core.ftl
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlheader-core.ftl b/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlheader-core.ftl
new file mode 100644
index 0000000..c07b867
--- /dev/null
+++ b/apps/showcase/src/main/resources/template/ajaxErrorContainers/controlheader-core.ftl
@@ -0,0 +1,80 @@
+<#--
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+<#--
+	Always include elements to show errors. They may be filled later via AJAX.
+-->
+<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>
+<#if (parameters.errorposition!"top") == 'top'>
+<tr errorFor="${parameters.id}">
+    <td class="tdErrorMessage" colspan="2" data-error-for-fieldname="${parameters.name}"><#rt/>
+        <#if hasFieldErrors>
+            <#list fieldErrors[parameters.name] as error>
+                <div class="errorMessage">${error?html}</div><#t/>
+            </#list>
+        </#if>
+    </td><#lt/>
+</tr>
+</#if>
+<#if !parameters.labelposition?? && (parameters.form.labelposition)??>
+<#assign labelpos = parameters.form.labelposition/>
+<#elseif parameters.labelposition??>
+<#assign labelpos = parameters.labelposition/>
+</#if>
+<#--
+	if the label position is top,
+	then give the label it's own row in the table
+-->
+<tr>
+<#if (labelpos!"") == 'top'>
+    <td class="tdLabelTop" colspan="2"><#rt/>
+<#else>
+    <td class="tdLabel"><#rt/>
+</#if>
+<#if parameters.label??>
+    <label <#t/>
+<#if parameters.id??>
+        for="${parameters.id?html}" <#t/>
+</#if>
+<#if hasFieldErrors>
+        class="errorLabel"<#t/>
+<#else>
+        class="label"<#t/>
+</#if>
+    ><#t/>
+<#if parameters.required!false && parameters.requiredPosition!"right" != 'right'>
+        <span class="required">*</span><#t/>
+</#if>
+${parameters.label?html}<#t/>
+<#if parameters.required!false && parameters.requiredPosition!"right" == 'right'>
+ <span class="required">*</span><#t/>
+</#if>
+${parameters.labelseparator!":"?html}<#t/>
+<#include "/${parameters.templateDir}/${parameters.expandTheme}/tooltip.ftl" />
+</label><#t/>
+</#if>
+    </td><#lt/>
+<#-- add the extra row -->
+<#if (labelpos!"") == 'top'>
+</tr>
+<tr>
+</#if>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/resources/template/ajaxErrorContainers/theme.properties
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/resources/template/ajaxErrorContainers/theme.properties b/apps/showcase/src/main/resources/template/ajaxErrorContainers/theme.properties
new file mode 100644
index 0000000..81346c7
--- /dev/null
+++ b/apps/showcase/src/main/resources/template/ajaxErrorContainers/theme.properties
@@ -0,0 +1,21 @@
+#
+# $Id$
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+parent = xhtml

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
index 1ca02cc..684a0f1 100644
--- a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
+++ b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
@@ -246,7 +246,6 @@
 					</li>
 					<li><s:a value="/interactive/index.action">Interactive Demo</s:a></li>
 				</ul>
-
 				<ul class="nav pull-right">
 					<li class="dropdown last">
 						<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-flag"></i> Help<b

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
new file mode 100644
index 0000000..c327802
--- /dev/null
+++ b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
@@ -0,0 +1,177 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+<html>
+<head>
+    <title>Struts2 Showcase - Validation - AJAX Form Submit</title>
+    <s:head theme="xhtml"/>
+
+    <style type="text/css">
+        /* see comment of script element below! */
+        .ajaxVisualFeedback {
+            width: 16px;
+            height: 16px;
+            background-image: url('../images/indicator.gif');
+            background-repeat: no-repeat;
+            float: right;
+        }
+    </style>
+
+</head>
+<body>
+
+<div class="page-header">
+    <h1>AJAX Form Submit</h1>
+</div>
+
+<div class="container-fluid">
+    <div class="row">
+        <div class="col-md-12">
+
+            <!-- START SNIPPET: ajaxFormSubmit -->
+
+            <h3>Action Errors Will Appear Here</h3>
+            <s:actionerror theme="ajaxErrorContainers"/>
+
+            <hr/>
+
+            <s:form method="POST" theme="xhtml">
+                <s:textfield label="Required Validator Field" name="requiredValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Required String Validator Field" name="requiredStringValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Integer Validator Field" name="integerValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Date Validator Field" name="dateValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Email Validator Field" name="emailValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="URL Validator Field" name="urlValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="String Length Validator Field" name="stringLengthValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Regex Validator Field" name="regexValidatorField" theme="ajaxErrorContainers"/>
+                <s:textfield label="Field Expression Validator Field" name="fieldExpressionValidatorField" theme="ajaxErrorContainers"/>
+                <s:submit label="Submit" cssClass="btn btn-primary"/>
+            </s:form>
+
+            <!-- END SNIPPET: ajaxFormSubmit -->
+        </div>
+    </div>
+</div>
+
+<script type="text/javascript">
+/********************************************************************
+ * JS just used on this page.
+ * Usually this would be placed in a JS file
+ * but as this showcase app is already hard to follow
+ * I place it here so it is easier to find.
+ *
+ * note: this requires jQuery.
+ *******************************************************************/
+
+ /**
+  * Validates given form per AJAX. To be called as onSubmit handler.
+  *
+  * @param event onSubmit event
+  */
+function ajaxFormValidation(event) {
+    event.preventDefault();
+    _removeValidationErrors();
+
+    var _form = $(event.target);
+    var _formData = _form.serialize(true);
+
+    // prepare visual feedback
+    // you may want to use other elements here
+    var originalButton = _form.find('.btn-primary');
+    // note: jQuery returns an array-like object
+    if (originalButton && originalButton.length && originalButton.length > 0) {
+        originalButton.hide();
+        var feedbackElement = $('<div class="ajaxVisualFeedback"></div>').insertAfter(originalButton);
+        var restoreFunction = function() {
+            originalButton.show();
+            feedbackElement.remove();
+        }
+    }
+
+
+    var options = {
+        data: 'struts.enableJSONValidation=true&struts.validateOnly=false&' + _formData,
+        async: true,
+        processData: false,
+        type: 'POST',
+        success: function (response, statusText, xhr) {
+            if (response.location) {
+                // no validation errors
+                // action has been executed and sent a redirect URL wrapped as JSON
+                // cannot use a normal http-redirect (status-code 3xx) as this would be followed by browsers and would not be available here
+
+                // follow JSON-redirect
+                window.location.href = response.location;
+            } else {
+                if (restoreFunction) {
+                    restoreFunction();
+                }
+                _handleValidationResult(_form, response);
+            }
+        },
+        error: function(xhr, textStatus, errorThrown) {
+            if (restoreFunction) {
+                restoreFunction();
+            }
+            // show user an error message
+            _handleValidationResult(_form, {errors: ['Network or server error!']})
+        }
+    }
+
+    // send request, after delay to make sure everybody notices the visual feedback :)
+    window.setTimeout(function() {
+        var url = _form[0].action;
+        jQuery.ajax(url, options);
+    }, 1000);
+}
+
+/**
+ * Removes validation errors from HTML DOM.
+ */
+function _removeValidationErrors() {
+    // action errors
+    // you might want to use a custom ID here
+    $('ul.errorMessage li').remove();
+
+    // field errors
+    $('div.errorMessage').remove();
+}
+
+/**
+ * Incorporates validation errors in HTML DOM.
+ *
+ * @param form Form containing errors.
+ * @param errors Errors from server.
+ * @returns {Boolean} True if form can be submitted.
+ */
+function _handleValidationResult(form, errors) {
+    // action errors
+    if (errors.errors) {
+        // you might want to use a custom ID here
+        var errorContainer = $('ul.errorMessage');
+        $.each(errors.errors, function(index, errorMsg) {
+            var li = $('<li><span></span></li>');
+            li.text(errorMsg);
+            errorContainer.append(li);
+        });
+    }
+
+    // field errors
+    if (errors.fieldErrors) {
+        $.each(errors.fieldErrors, function(fieldName, errorMsg) {
+            var td = $('td[data-error-for-fieldname="' + fieldName + '"]');
+            if (td) {
+                var div = $('<div class="errorMessage"></div>');
+                div.text(errorMsg);
+                td.append(div);
+            }
+        });
+    }
+}
+
+// register onSubmit handler
+$(window).bind('load', function() {
+    $('form').bind('submit', ajaxFormValidation);
+});
+</script>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmitSuccess.jsp
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmitSuccess.jsp b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmitSuccess.jsp
new file mode 100644
index 0000000..f8a0731
--- /dev/null
+++ b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmitSuccess.jsp
@@ -0,0 +1,17 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+<html>
+<head>
+	<title>Struts2 Showcase - Validation - Success Field Validators Example</title>
+	<s:head/>
+</head>
+<body>
+
+<div class="page-header">
+	<h1>Success !</h1>
+</div>
+
+<div class="container-fluid">
+Form has been submitted.
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/apps/showcase/src/main/webapp/WEB-INF/validation/index.jsp
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/webapp/WEB-INF/validation/index.jsp b/apps/showcase/src/main/webapp/WEB-INF/validation/index.jsp
index 96a331f..00c1579 100644
--- a/apps/showcase/src/main/webapp/WEB-INF/validation/index.jsp
+++ b/apps/showcase/src/main/webapp/WEB-INF/validation/index.jsp
@@ -31,6 +31,7 @@
 			<s:url var="clientSideValidationUrl" action="clientSideValidationExample" namespace="/validation"/>
 			<s:url var="backToShowcase" action="showcase" namespace="/"/>
 			<s:url var="storeMessageAcrossRequestExample" namespace="/validation" action="storeErrorsAcrossRequestExample"/>
+			<s:url var="ajaxFormSubmitAction" namespace="/validation" action="ajaxFormSubmit!input"/>
 
 			<ul>
 				<li><s:a href="%{fieldValidatorUrl}">Field Validators</s:a></li>
@@ -42,6 +43,7 @@
 				<li><s:a href="%{quizClient}">Validation (client)</s:a></li>
 				<li><s:a href="%{quizClientCss}">Validation (client using css_xhtml theme)</s:a></li>
 				<li><s:a href="%{visitorValidatorUrl}">Visitor Validator</s:a></li>
+				<li><s:a href="%{ajaxFormSubmitAction}">AJAX Form Submit</s:a></li>
 			</ul>
 		</div>
 	</div>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
new file mode 100644
index 0000000..f9b28b2
--- /dev/null
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
@@ -0,0 +1,71 @@
+package org.apache.struts2.json;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+/**
+ * Specialized form of {@link ServletActionRedirectResult} which takes care of
+ * situation that browser has a JS/AJAX context, there are no validation errors
+ * and action is executed. In this case a http redirect is harmful as browsers
+ * don't pass them to JS handlers. So this result produces a JSON response
+ * containing redirect data.
+ *
+ *<p>
+ * To be used along with {@link JSONValidationInterceptor}.
+ *</p>
+ *<p>
+ * Response JSON looks like this:
+ * <pre>{"location": "$redirect url$"}</pre>
+ *</p>
+ *
+ */
+public class JSONActionRedirectResult extends ServletActionRedirectResult {
+
+    private static final long serialVersionUID = 3107276294073879542L;
+
+    @Override
+	protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException {
+        if (sendJsonInsteadOfRedirect()) {
+            printJson(response, finalLocation);
+        } else {
+            super.sendRedirect(response, finalLocation);
+        }
+    }
+
+    /**
+     * If browser has called action in a JS/AJAX context we cannot send a
+     * redirect as response.
+     *
+     * @return true if a JSON response shall be generated, false if a redirect
+     *         shall be sent.
+     */
+    static boolean sendJsonInsteadOfRedirect() {
+        HttpServletRequest request = ServletActionContext.getRequest();
+        return isJsonEnabled(request) && !isValidateOnly(request);
+    }
+
+    static void printJson(HttpServletResponse response, String finalLocation) throws IOException {
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setContentType("application/json");
+        response.setHeader("Location", finalLocation);
+        PrintWriter writer = response.getWriter();
+        writer.write("{\"location\": \"");
+        writer.write(finalLocation);
+        writer.write("\"}");
+        writer.close();
+    }
+
+    private static boolean isJsonEnabled(HttpServletRequest request) {
+        return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_JSON_PARAM));
+    }
+
+    private static boolean isValidateOnly(HttpServletRequest request) {
+        return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_ONLY_PARAM));
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
index 8194205..1c7fd54 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
@@ -61,6 +61,8 @@ import java.util.Map;
  * <p>If the request has a parameter 'struts.validateOnly' execution will return after
  * validation (action won't be executed).</p>
  *
+ * <p>If 'struts.validateOnly' is set to false you may want to use {@link JSONActionRedirectResult}.</p>
+ *
  * <p>A request parameter named 'struts.enableJSONValidation' must be set to 'true' to
  * use this interceptor</p>
  *
@@ -72,8 +74,8 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
 
     private static final Logger LOG = LoggerFactory.getLogger(JSONValidationInterceptor.class);
 
-    private static final String VALIDATE_ONLY_PARAM = "struts.validateOnly";
-    private static final String VALIDATE_JSON_PARAM = "struts.enableJSONValidation";
+    static final String VALIDATE_ONLY_PARAM = "struts.validateOnly";
+    static final String VALIDATE_JSON_PARAM = "struts.enableJSONValidation";
     private static final String NO_ENCODING_SET_PARAM = "struts.JSONValidation.no.encoding";
 
     private static final String DEFAULT_ENCODING = "UTF-8";

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/plugins/json/src/main/resources/struts-plugin.xml
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/resources/struts-plugin.xml b/plugins/json/src/main/resources/struts-plugin.xml
index 5abfbea..58c06c7 100644
--- a/plugins/json/src/main/resources/struts-plugin.xml
+++ b/plugins/json/src/main/resources/struts-plugin.xml
@@ -9,6 +9,7 @@
 
         <result-types>
             <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
+            <result-type name="jsonActionRedirect" class="org.apache.struts2.json.JSONActionRedirectResult"/>
         </result-types>
 
         <interceptors>

http://git-wip-us.apache.org/repos/asf/struts/blob/69bc2947/plugins/json/src/test/java/org/apache/struts2/json/JSONActionRedirectResultTest.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/test/java/org/apache/struts2/json/JSONActionRedirectResultTest.java b/plugins/json/src/test/java/org/apache/struts2/json/JSONActionRedirectResultTest.java
new file mode 100644
index 0000000..c98e41a
--- /dev/null
+++ b/plugins/json/src/test/java/org/apache/struts2/json/JSONActionRedirectResultTest.java
@@ -0,0 +1,105 @@
+package org.apache.struts2.json;
+
+import org.apache.struts2.StrutsStatics;
+import org.apache.struts2.StrutsTestCase;
+import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
+import org.apache.struts2.views.util.DefaultUrlHelper;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletContext;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.mock.MockActionInvocation;
+import com.opensymphony.xwork2.mock.MockActionProxy;
+import com.opensymphony.xwork2.util.ValueStack;
+
+public class JSONActionRedirectResultTest extends StrutsTestCase {
+
+    MockActionInvocation invocation;
+    MockHttpServletResponse response;
+    MockServletContext servletContext;
+    ActionContext context;
+    ValueStack stack;
+    MockHttpServletRequest request;
+
+    public void testNormalRedirect() throws Exception {
+        JSONActionRedirectResult result = new JSONActionRedirectResult();
+        result.setActionName("targetAction");
+        result.setActionMapper(new DefaultActionMapper());
+        result.setUrlHelper(new DefaultUrlHelper());
+
+        Object action = new Object();
+        stack.push(action);
+
+        this.invocation.setAction(action);
+        result.execute(this.invocation);
+
+        String content = response.getContentAsString();
+        assertEquals("", content);
+        String location = response.getHeader("Location");
+        assertEquals("/targetAction.action", location);
+        assertEquals(302, response.getStatus());
+    }
+
+    public void testJsonRedirect() throws Exception {
+        JSONActionRedirectResult result = new JSONActionRedirectResult();
+        result.setActionName("targetAction");
+        result.setActionMapper(new DefaultActionMapper());
+        result.setUrlHelper(new DefaultUrlHelper());
+
+        request.setParameter("struts.enableJSONValidation", "true");
+        request.setParameter("struts.validateOnly", "false");
+
+        Object action = new Object();
+        stack.push(action);
+
+        this.invocation.setAction(action);
+        result.execute(this.invocation);
+
+        String content = response.getContentAsString();
+        assertEquals("{\"location\": \"/targetAction.action\"}", content);
+        assertEquals(200, response.getStatus());
+    }
+
+    public void testValidateOnlyFalse() throws Exception {
+        JSONActionRedirectResult result = new JSONActionRedirectResult();
+        result.setActionName("targetAction");
+        result.setActionMapper(new DefaultActionMapper());
+        result.setUrlHelper(new DefaultUrlHelper());
+
+        request.setParameter("struts.enableJSONValidation", "true");
+        request.setParameter("struts.validateOnly", "true");
+
+        Object action = new Object();
+        stack.push(action);
+
+        this.invocation.setAction(action);
+        result.execute(this.invocation);
+
+        String content = response.getContentAsString();
+        assertEquals("", content);
+        String location = response.getHeader("Location");
+        assertEquals("/targetAction.action", location);
+        assertEquals(302, response.getStatus());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.response = new MockHttpServletResponse();
+        this.request = new MockHttpServletRequest();
+        this.context = ActionContext.getContext();
+        this.context.put(StrutsStatics.HTTP_RESPONSE, this.response);
+        this.context.put(StrutsStatics.HTTP_REQUEST, this.request);
+        this.stack = context.getValueStack();
+        this.servletContext = new MockServletContext();
+        this.context.put(StrutsStatics.SERVLET_CONTEXT, this.servletContext);
+        this.invocation = new MockActionInvocation();
+        this.invocation.setInvocationContext(this.context);
+        this.invocation.setStack(this.stack);
+        MockActionProxy mockActionProxy = new MockActionProxy();
+        mockActionProxy.setConfig(new ActionConfig.Builder(null, null, null).build());
+        this.invocation.setProxy(mockActionProxy);
+    }
+}


[2/4] struts git commit: made methods non static and private, javadoc updates

Posted by cn...@apache.org.
made methods non static and private, javadoc updates

Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/6438396e
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/6438396e
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/6438396e

Branch: refs/heads/support-2-3
Commit: 6438396ef83560f89d18975a5a49dcb336b272f7
Parents: 69bc294
Author: cnenning <cn...@apache.org>
Authored: Tue Jan 12 14:14:09 2016 +0100
Committer: cnenning <cn...@apache.org>
Committed: Fri Jan 29 13:53:48 2016 +0100

----------------------------------------------------------------------
 .../validation/AjaxFormSubmitAction.java        |  2 +-
 .../struts2/json/JSONActionRedirectResult.java  | 23 ++++++++++----------
 2 files changed, 12 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/6438396e/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
index b179370..50ff53f 100644
--- a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
+++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AjaxFormSubmitAction.java
@@ -23,7 +23,7 @@ import com.opensymphony.xwork2.validator.annotations.UrlValidator;
  * <ul>
  *   <li>Depends on <code>json-plugin</code>.</li>
  *   <li>Requires <code>jsonValidationInterceptor</code> to be on stack.</li>
- *   <li>Uses a special json redirect result type.</li>
+ *   <li>Uses result type <code>jsonActionRedirect</code>.</li>
  *   <li>Uses http parameters <code>struts.enableJSONValidation=true</code> and <code>struts.validateOnly=false</code>.</li>
  *   <li>Uses a customized theme to make sure html elements required as error containers are always present and easily selectable in JS.</li>
  *   <li>Uses some custom JS code depending on jQuery to issue AJAX request and to render errors in html.</li>

http://git-wip-us.apache.org/repos/asf/struts/blob/6438396e/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
index f9b28b2..65d0bd3 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
@@ -16,13 +16,12 @@ import org.apache.struts2.dispatcher.ServletActionRedirectResult;
  * don't pass them to JS handlers. So this result produces a JSON response
  * containing redirect data.
  *
- *<p>
- * To be used along with {@link JSONValidationInterceptor}.
- *</p>
- *<p>
- * Response JSON looks like this:
- * <pre>{"location": "$redirect url$"}</pre>
- *</p>
+ * <p>To be used along with {@link JSONValidationInterceptor}.</p>
+ *
+ * <p>Response JSON looks like this:
+ * 
+ *     <pre>{"location": "$redirect url$"}</pre>
+ * </p>
  *
  */
 public class JSONActionRedirectResult extends ServletActionRedirectResult {
@@ -30,7 +29,7 @@ public class JSONActionRedirectResult extends ServletActionRedirectResult {
     private static final long serialVersionUID = 3107276294073879542L;
 
     @Override
-	protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException {
+    protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException {
         if (sendJsonInsteadOfRedirect()) {
             printJson(response, finalLocation);
         } else {
@@ -45,12 +44,12 @@ public class JSONActionRedirectResult extends ServletActionRedirectResult {
      * @return true if a JSON response shall be generated, false if a redirect
      *         shall be sent.
      */
-    static boolean sendJsonInsteadOfRedirect() {
+    private boolean sendJsonInsteadOfRedirect() {
         HttpServletRequest request = ServletActionContext.getRequest();
         return isJsonEnabled(request) && !isValidateOnly(request);
     }
 
-    static void printJson(HttpServletResponse response, String finalLocation) throws IOException {
+    private void printJson(HttpServletResponse response, String finalLocation) throws IOException {
         response.setStatus(HttpServletResponse.SC_OK);
         response.setContentType("application/json");
         response.setHeader("Location", finalLocation);
@@ -61,11 +60,11 @@ public class JSONActionRedirectResult extends ServletActionRedirectResult {
         writer.close();
     }
 
-    private static boolean isJsonEnabled(HttpServletRequest request) {
+    private boolean isJsonEnabled(HttpServletRequest request) {
         return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_JSON_PARAM));
     }
 
-    private static boolean isValidateOnly(HttpServletRequest request) {
+    private boolean isValidateOnly(HttpServletRequest request) {
         return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_ONLY_PARAM));
     }
 }


[4/4] struts git commit: updated comments

Posted by cn...@apache.org.
updated comments


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/2a6acabe
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/2a6acabe
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/2a6acabe

Branch: refs/heads/support-2-3
Commit: 2a6acabe5d53ba01073f8471c56f95ac31087bd3
Parents: 377c6cd
Author: cnenning <cn...@apache.org>
Authored: Thu Jan 28 10:58:44 2016 +0100
Committer: cnenning <cn...@apache.org>
Committed: Fri Jan 29 13:54:31 2016 +0100

----------------------------------------------------------------------
 .../src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp     | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/2a6acabe/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
----------------------------------------------------------------------
diff --git a/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
index c327802..f30403f 100644
--- a/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
+++ b/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp
@@ -63,7 +63,7 @@
  *******************************************************************/
 
  /**
-  * Validates given form per AJAX. To be called as onSubmit handler.
+  * Validates form per AJAX. To be called as onSubmit handler.
   *
   * @param event onSubmit event
   */
@@ -141,7 +141,6 @@ function _removeValidationErrors() {
  *
  * @param form Form containing errors.
  * @param errors Errors from server.
- * @returns {Boolean} True if form can be submitted.
  */
 function _handleValidationResult(form, errors) {
     // action errors
@@ -150,7 +149,7 @@ function _handleValidationResult(form, errors) {
         var errorContainer = $('ul.errorMessage');
         $.each(errors.errors, function(index, errorMsg) {
             var li = $('<li><span></span></li>');
-            li.text(errorMsg);
+            li.text(errorMsg); // use text() for security reasons
             errorContainer.append(li);
         });
     }
@@ -161,7 +160,7 @@ function _handleValidationResult(form, errors) {
             var td = $('td[data-error-for-fieldname="' + fieldName + '"]');
             if (td) {
                 var div = $('<div class="errorMessage"></div>');
-                div.text(errorMsg);
+                div.text(errorMsg); // use text() for security reasons
                 td.append(div);
             }
         });


[3/4] struts git commit: increased visibilty of methods and constants for better extensibility

Posted by cn...@apache.org.
increased visibilty of methods and constants for better extensibility


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/377c6cdd
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/377c6cdd
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/377c6cdd

Branch: refs/heads/support-2-3
Commit: 377c6cdda03cd1faf95c664e706b7e389f12058b
Parents: 6438396
Author: cnenning <cn...@apache.org>
Authored: Thu Jan 14 09:33:50 2016 +0100
Committer: cnenning <cn...@apache.org>
Committed: Fri Jan 29 13:54:08 2016 +0100

----------------------------------------------------------------------
 .../org/apache/struts2/json/JSONActionRedirectResult.java    | 8 ++++----
 .../org/apache/struts2/json/JSONValidationInterceptor.java   | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/377c6cdd/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
index 65d0bd3..d672c91 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java
@@ -44,12 +44,12 @@ public class JSONActionRedirectResult extends ServletActionRedirectResult {
      * @return true if a JSON response shall be generated, false if a redirect
      *         shall be sent.
      */
-    private boolean sendJsonInsteadOfRedirect() {
+    protected boolean sendJsonInsteadOfRedirect() {
         HttpServletRequest request = ServletActionContext.getRequest();
         return isJsonEnabled(request) && !isValidateOnly(request);
     }
 
-    private void printJson(HttpServletResponse response, String finalLocation) throws IOException {
+    protected void printJson(HttpServletResponse response, String finalLocation) throws IOException {
         response.setStatus(HttpServletResponse.SC_OK);
         response.setContentType("application/json");
         response.setHeader("Location", finalLocation);
@@ -60,11 +60,11 @@ public class JSONActionRedirectResult extends ServletActionRedirectResult {
         writer.close();
     }
 
-    private boolean isJsonEnabled(HttpServletRequest request) {
+    protected boolean isJsonEnabled(HttpServletRequest request) {
         return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_JSON_PARAM));
     }
 
-    private boolean isValidateOnly(HttpServletRequest request) {
+    protected boolean isValidateOnly(HttpServletRequest request) {
         return "true".equals(request.getParameter(JSONValidationInterceptor.VALIDATE_ONLY_PARAM));
     }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/377c6cdd/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
index 1c7fd54..fc65324 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java
@@ -74,11 +74,11 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
 
     private static final Logger LOG = LoggerFactory.getLogger(JSONValidationInterceptor.class);
 
-    static final String VALIDATE_ONLY_PARAM = "struts.validateOnly";
-    static final String VALIDATE_JSON_PARAM = "struts.enableJSONValidation";
-    private static final String NO_ENCODING_SET_PARAM = "struts.JSONValidation.no.encoding";
+    public static final String VALIDATE_ONLY_PARAM = "struts.validateOnly";
+    public static final String VALIDATE_JSON_PARAM = "struts.enableJSONValidation";
+    public static final String NO_ENCODING_SET_PARAM = "struts.JSONValidation.no.encoding";
 
-    private static final String DEFAULT_ENCODING = "UTF-8";
+    public static final String DEFAULT_ENCODING = "UTF-8";
 
     private int validationFailedStatus = -1;