Repository: struts
Updated Branches:
  refs/heads/master 7dbe3ea8b -> 547718fcc


WW-4684 Uses Content-Type to perform action based on defined type


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

Branch: refs/heads/master
Commit: 547718fcc6e1d694cfd6ef5a65a5c42edb49a3dc
Parents: 7dbe3ea
Author: Lukasz Lenart <lukaszlen...@apache.org>
Authored: Mon Sep 5 12:02:00 2016 +0200
Committer: Lukasz Lenart <lukaszlen...@apache.org>
Committed: Mon Sep 5 12:02:00 2016 +0200

----------------------------------------------------------------------
 .../apache/struts2/json/JSONInterceptor.java    | 180 ++++++++++---------
 .../struts2/json/JSONInterceptorTest.java       |  28 +--
 2 files changed, 112 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/547718fc/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
----------------------------------------------------------------------
diff --git 
a/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java 
b/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
index b4ad4b7..d7836eb 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
@@ -70,20 +70,17 @@ public class JSONInterceptor extends AbstractInterceptor {
     private boolean noCache = false;
     private boolean excludeNullProperties;
     private String callbackParameter;
-    private String accept;
+    private String jsonContentType = "application/json";
+    private String jsonRpcContentType = "application/json-rpc";
 
     @SuppressWarnings("unchecked")
     public String intercept(ActionInvocation invocation) throws Exception {
         HttpServletRequest request = ServletActionContext.getRequest();
         HttpServletResponse response = ServletActionContext.getResponse();
         
-        //parameter wasn't set by the interceptor
-        if (accept == null) {
-            accept = request.getHeader("accept");
-        }
-        
-        String[] accepts = accept.split(",");
-        
+        String requestContentType = readContentType(request);
+        String requestContentTypeEncoding = readContentTypeEncoding(request);
+
         Object rootObject = null;
         final ValueStack stack = invocation.getStack();
         if (this.root != null) {
@@ -94,103 +91,118 @@ public class JSONInterceptor extends AbstractInterceptor {
             }
         }
 
-        for (String accept : accepts) {
-            if ((accept != null) && 
accept.equalsIgnoreCase("application/json")) {
-                // load JSON object
-                Object obj = JSONUtil.deserialize(request.getReader());
+        if (jsonContentType.equalsIgnoreCase(requestContentType)) {
+            // load JSON object
+            Object obj = JSONUtil.deserialize(request.getReader());
 
-                // JSON array (this.root cannot be null in this case)
-                if(obj instanceof List && this.root != null) {
-                    String mapKey = this.root;
-                    rootObject = null;
+            // JSON array (this.root cannot be null in this case)
+            if(obj instanceof List && this.root != null) {
+                String mapKey = this.root;
+                rootObject = null;
 
-                    if(this.root.indexOf('.') != -1) {
-                        mapKey = 
this.root.substring(this.root.lastIndexOf('.') + 1);
+                if(this.root.indexOf('.') != -1) {
+                    mapKey = this.root.substring(this.root.lastIndexOf('.') + 
1);
 
-                        rootObject = stack.findValue(this.root.substring(0, 
this.root.lastIndexOf('.')));
-                        if (rootObject == null) {
-                            throw new RuntimeException("JSON array: Invalid 
root expression: '" + this.root + "'.");
-                        }
+                    rootObject = stack.findValue(this.root.substring(0, 
this.root.lastIndexOf('.')));
+                    if (rootObject == null) {
+                        throw new RuntimeException("JSON array: Invalid root 
expression: '" + this.root + "'.");
                     }
-
-                    // create a map with a list inside
-                    Map m = new HashMap();
-                    m.put(mapKey, new ArrayList((List) obj));
-                    obj = m;
                 }
 
-                if (obj instanceof Map) {
-                    Map json = (Map) obj;
+                // create a map with a list inside
+                Map m = new HashMap();
+                m.put(mapKey, new ArrayList((List) obj));
+                obj = m;
+            }
 
-                    // clean up the values
-                    if (dataCleaner != null)
-                        dataCleaner.clean("", json);
+            if (obj instanceof Map) {
+                Map json = (Map) obj;
 
-                    if (rootObject == null) // model overrides action
-                        rootObject = invocation.getStack().peek();
+                // clean up the values
+                if (dataCleaner != null)
+                    dataCleaner.clean("", json);
 
-                    // populate fields
-                    populator.populateObject(rootObject, json);
-                } else {
-                    LOG.error("Unable to deserialize JSON object from 
request");
-                    throw new JSONException("Unable to deserialize JSON object 
from request");
-                }
-            } else if ((accept != null) && 
accept.equalsIgnoreCase("application/json-rpc")) {
-                Object result;
-                if (this.enableSMD) {
-                    // load JSON object
-                    Object obj = JSONUtil.deserialize(request.getReader());
-
-                    if (obj instanceof Map) {
-                        Map smd = (Map) obj;
-
-                        if (rootObject == null) { // model makes no sense when 
using RPC
-                            rootObject = invocation.getAction();
-                        }
-
-                        // invoke method
-                        try {
-                            result = this.invoke(rootObject, smd);
-                        } catch (Exception e) {
-                            RPCResponse rpcResponse = new RPCResponse();
-                            rpcResponse.setId(smd.get("id").toString());
-                            rpcResponse.setError(new RPCError(e, 
RPCErrorCode.EXCEPTION, getDebug()));
-
-                            result = rpcResponse;
-                        }
-                    } else {
-                        String message = "SMD request was not in the right 
format. See http://json-rpc.org";;
+                if (rootObject == null) // model overrides action
+                    rootObject = invocation.getStack().peek();
+
+                // populate fields
+                populator.populateObject(rootObject, json);
+            } else {
+                LOG.error("Unable to deserialize JSON object from request");
+                throw new JSONException("Unable to deserialize JSON object 
from request");
+            }
+        } else if (jsonRpcContentType.equalsIgnoreCase(requestContentType)) {
+            Object result;
+            if (this.enableSMD) {
+                // load JSON object
+                Object obj = JSONUtil.deserialize(request.getReader());
 
+                if (obj instanceof Map) {
+                    Map smd = (Map) obj;
+
+                    if (rootObject == null) { // model makes no sense when 
using RPC
+                        rootObject = invocation.getAction();
+                    }
+
+                    // invoke method
+                    try {
+                        result = this.invoke(rootObject, smd);
+                    } catch (Exception e) {
                         RPCResponse rpcResponse = new RPCResponse();
-                        rpcResponse.setError(new RPCError(message, 
RPCErrorCode.INVALID_PROCEDURE_CALL));
+                        rpcResponse.setId(smd.get("id").toString());
+                        rpcResponse.setError(new RPCError(e, 
RPCErrorCode.EXCEPTION, getDebug()));
+
                         result = rpcResponse;
                     }
                 } else {
-                    String message = "Request with content type of 
'application/json-rpc' was received but SMD is "
-                            + "not enabled for this interceptor. Set 
'enableSMD' to true to enable it";
+                    String message = "SMD request was not in the right format. 
See http://json-rpc.org";;
 
                     RPCResponse rpcResponse = new RPCResponse();
-                    rpcResponse.setError(new RPCError(message, 
RPCErrorCode.SMD_DISABLED));
+                    rpcResponse.setError(new RPCError(message, 
RPCErrorCode.INVALID_PROCEDURE_CALL));
                     result = rpcResponse;
                 }
+            } else {
+                String message = "Request with content type of 
'application/json-rpc' was received but SMD is "
+                        + "not enabled for this interceptor. Set 'enableSMD' 
to true to enable it";
 
-                String json = JSONUtil.serialize(result, excludeProperties, 
getIncludeProperties(),
-                        ignoreHierarchy, excludeNullProperties);
-                json = addCallbackIfApplicable(request, json);
-                boolean writeGzip = enableGZIP && 
JSONUtil.isGzipInRequest(request);
-                JSONUtil.writeJSONToResponse(new SerializationParams(response, 
this.defaultEncoding,
-                        this.wrapWithComments, json, true, writeGzip, noCache, 
-1, -1, prefix, "application/json"));
-
-                return Action.NONE;
-            } else {            
-                LOG.debug("Accept header parameter must be 'application/json' 
or 'application/json-rpc'. Ignoring request with accept ", accept);
-                break;
+                RPCResponse rpcResponse = new RPCResponse();
+                rpcResponse.setError(new RPCError(message, 
RPCErrorCode.SMD_DISABLED));
+                result = rpcResponse;
             }
+
+            String json = JSONUtil.serialize(result, excludeProperties, 
getIncludeProperties(),
+                    ignoreHierarchy, excludeNullProperties);
+            json = addCallbackIfApplicable(request, json);
+            boolean writeGzip = enableGZIP && 
JSONUtil.isGzipInRequest(request);
+            JSONUtil.writeJSONToResponse(new SerializationParams(response, 
requestContentTypeEncoding,
+                    this.wrapWithComments, json, true, writeGzip, noCache, -1, 
-1, prefix, "application/json"));
+
+            return Action.NONE;
+        } else {
+            LOG.debug("Accept header parameter must be '{}' or '{}'. Ignoring 
request with Content Type '{}'", jsonContentType, jsonRpcContentType, 
requestContentType);
         }
 
         return invocation.invoke();
     }
 
+    protected String readContentType(HttpServletRequest request) {
+        String contentType = request.getHeader("Content-Type");
+        if (contentType != null && contentType.contains(";")) {
+            contentType = contentType.substring(0, contentType.indexOf(";"));
+        }
+        return contentType;
+    }
+
+    protected String readContentTypeEncoding(HttpServletRequest request) {
+        String contentTypeEncoding = request.getHeader("Content-Type");
+        if (contentTypeEncoding != null && 
contentTypeEncoding.contains(";encoding=")) {
+            contentTypeEncoding = 
contentTypeEncoding.substring(contentTypeEncoding.indexOf(";encoding=") + 
";encoding=".length());
+        } else {
+            contentTypeEncoding = defaultEncoding;
+        }
+        return contentTypeEncoding;
+    }
+
     @SuppressWarnings("unchecked")
     public RPCResponse invoke(Object object, Map data) throws 
IllegalArgumentException,
             IllegalAccessException, InvocationTargetException, JSONException, 
InstantiationException,
@@ -539,7 +551,11 @@ public class JSONInterceptor extends AbstractInterceptor {
         this.prefix = prefix;
     }
 
-    public void setAccept(String accept) {
-        this.accept = accept;
+    public void setJsonContentType(String jsonContentType) {
+        this.jsonContentType = jsonContentType;
+    }
+
+    public void setJsonRpcContentType(String jsonRpcContentType) {
+        this.jsonRpcContentType = jsonRpcContentType;
     }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/547718fc/plugins/json/src/test/java/org/apache/struts2/json/JSONInterceptorTest.java
----------------------------------------------------------------------
diff --git 
a/plugins/json/src/test/java/org/apache/struts2/json/JSONInterceptorTest.java 
b/plugins/json/src/test/java/org/apache/struts2/json/JSONInterceptorTest.java
index 85e64ec..ac4c39b 100644
--- 
a/plugins/json/src/test/java/org/apache/struts2/json/JSONInterceptorTest.java
+++ 
b/plugins/json/src/test/java/org/apache/struts2/json/JSONInterceptorTest.java
@@ -71,7 +71,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     private void tryBadJSON(String fileName) throws Exception {
         // request
         setRequestContent(fileName);
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", 
"application/json;encoding=UTF-8");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -92,7 +92,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDDisabledSMD() throws Exception {
         // request
         setRequestContent("smd-3.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         SMDActionTest1 action = new SMDActionTest1();
@@ -111,7 +111,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDAliasedMethodCall1() throws Exception {
         // request
         setRequestContent("smd-14.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -129,7 +129,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDAliasedMethodCall2() throws Exception {
         // request
         setRequestContent("smd-15.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -147,7 +147,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDNoMethod() throws Exception {
         // request
         setRequestContent("smd-4.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -171,7 +171,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDMethodWithoutAnnotations() throws Exception {
         // request
         setRequestContent("smd-9.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -192,7 +192,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDPrimitivesNoResult() throws Exception {
         // request
         setRequestContent("smd-6.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -227,7 +227,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDReturnObject() throws Exception {
         // request
         setRequestContent("smd-10.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -252,7 +252,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testSMDObjectsNoResult() throws Exception {
         // request
         setRequestContent("smd-7.txt");
-        this.request.addHeader("accept", "application/json-rpc, text/plain, 
*/*");
+        this.request.addHeader("Content-Type", "application/json-rpc");
 
         JSONInterceptor interceptor = new JSONInterceptor();
         interceptor.setEnableSMD(true);
@@ -300,7 +300,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void testReadEmpty() throws Exception {
         // request
         setRequestContent("json-6.txt");
-        this.request.addHeader("accept", "application/json, text/plain, */*");
+        this.request.addHeader("Content-Type", "application/json");
 
         // interceptor
         JSONInterceptor interceptor = new JSONInterceptor();
@@ -315,7 +315,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     public void test() throws Exception {
         // request
         setRequestContent("json-1.txt");
-        this.request.addHeader("accept", "application/json, text/plain, */*");
+        this.request.addHeader("Content-Type", "application/json");
 
         // interceptor
         JSONInterceptor interceptor = new JSONInterceptor();
@@ -437,7 +437,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
 
     public void testRoot() throws Exception {
         setRequestContent("json-5.txt");
-        this.request.addHeader("accept", "application/json, text/plain, */*");
+        this.request.addHeader("Content-Type", "application/json");
 
         // interceptor
         JSONInterceptor interceptor = new JSONInterceptor();
@@ -462,7 +462,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
     
     public void testJSONArray() throws Exception {
         setRequestContent("json-12.txt");
-        this.request.addHeader("accept", "application/json, text/plain, */*");
+        this.request.addHeader("Content-Type", "application/json");
 
         // interceptor
         JSONInterceptor interceptor = new JSONInterceptor();
@@ -488,7 +488,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
 
     public void testJSONArray2() throws Exception {
         setRequestContent("json-12.txt");
-        this.request.addHeader("accept", "application/json, text/plain, */*");
+        this.request.addHeader("Content-Type", "application/json");
 
         // interceptor
         JSONInterceptor interceptor = new JSONInterceptor();

Reply via email to