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

struts git commit: WW-4588: Improve the Struts2 Rest plugin to honor Accept header

Repository: struts
Updated Branches:
  refs/heads/support-2-3 10a612c9d -> 2ec3890dc


WW-4588:  Improve the Struts2 Rest plugin to honor Accept header

Conflicts:
	plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java


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

Branch: refs/heads/support-2-3
Commit: 2ec3890dc7d704d3098e1bd738bff9ae5ca4f989
Parents: 10a612c
Author: petersr <ri...@braxtontech.com>
Authored: Wed Jan 20 06:34:25 2016 -0800
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Jan 20 16:12:55 2016 +0100

----------------------------------------------------------------------
 .../rest/DefaultContentTypeHandlerManager.java  | 69 +++++++++++++++++---
 .../DefaultContentTypeHandlerManagerTest.java   | 42 ++++++++++++
 2 files changed, 103 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/2ec3890d/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java
----------------------------------------------------------------------
diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java b/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java
index c55f319..dba7d13 100644
--- a/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java
+++ b/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java
@@ -42,9 +42,9 @@ import java.util.Set;
 public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManager {
 
     /** ContentTypeHandlers keyed by the extension */
-    Map<String,ContentTypeHandler> handlersByExtension = new HashMap<String,ContentTypeHandler>();
+    Map<String, ContentTypeHandler> handlersByExtension = new HashMap<String, ContentTypeHandler>();
     /** ContentTypeHandlers keyed by the content-type */
-    Map<String,ContentTypeHandler> handlersByContentType = new HashMap<String,ContentTypeHandler>();
+    Map<String, ContentTypeHandler> handlersByContentType = new HashMap<String, ContentTypeHandler>();
 
     private String defaultExtension;
 
@@ -61,7 +61,7 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
 
             if (handler.getExtension() != null) {
                 // Check for overriding handlers for the current extension
-                String overrideName = container.getInstance(String.class, STRUTS_REST_HANDLER_OVERRIDE_PREFIX +handler.getExtension());
+                String overrideName = container.getInstance(String.class, STRUTS_REST_HANDLER_OVERRIDE_PREFIX + handler.getExtension());
                 if (overrideName != null) {
                     if (!handlersByExtension.containsKey(handler.getExtension())) {
                         handler = container.getInstance(ContentTypeHandler.class, overrideName);
@@ -74,7 +74,15 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
             }
 
             if (handler.getContentType() != null) {
-                this.handlersByContentType.put(handler.getContentType(), handler);
+                //dont store character encoding
+                String typeOnly = handler.getContentType() ;
+                int index = handler.getContentType().indexOf(';');
+                if (index != -1)
+                {
+                    typeOnly = handler.getContentType().substring(0, index).trim();
+                }
+
+                this.handlersByContentType.put(typeOnly, handler);
             }
         }
     }
@@ -109,12 +117,42 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
      * Gets the handler for the response by looking at the extension of the request
      * @param req The request
      * @return The appropriate handler
+     *
+     * WW-4588: modified to get a handler for the response side and auto generate the response type
+     * from the Accept: header
+     *
      */
-    public ContentTypeHandler getHandlerForResponse(HttpServletRequest req, HttpServletResponse res) {
-        String extension = findExtension(req.getRequestURI());
+    public ContentTypeHandler getHandlerForResponse(HttpServletRequest request, HttpServletResponse res) {
+
+        String extension = getExtensionIfPresent(request.getRequestURI());
+        if (extension == null) {
+            extension = defaultExtension;
+            final String acceptHeader = request.getHeader("accept") ;
+            if (acceptHeader != null) {
+                final String[] types = acceptHeader.split(",");
+                for (final String type : types) {
+                    final ContentTypeHandler handler = findHandler(type);
+                    if (handler != null) {
+                        return handler;
+                    }
+                }
+            }
+        }
         return handlersByExtension.get(extension);
     }
 
+    private ContentTypeHandler findHandler(final String type) {
+        ContentTypeHandler handler = handlersByContentType.get(type);
+        if (handler == null) {
+            // strip off encoding and search again (e.g., application/json;charset=ISO-8859-1)
+            final int index = type.indexOf(';');
+            if (index != -1) {
+                return handlersByContentType.get(type.substring(0, index).trim());
+            }
+        }
+        return handler;
+    }
+
     /**
      * Handles the result using handlers to generate content type-specific content
      * 
@@ -175,16 +213,31 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
     }
 
     /**
+     * Gets the extension in the url
+     *
+     * @param url The url
+     * @return The extension, or null
+     */
+    public String getExtensionIfPresent(String url) {
+        int dotPos = url.lastIndexOf('.');
+        int slashPos = url.lastIndexOf('/');
+        if (dotPos > slashPos && dotPos > -1) {
+            return url.substring(dotPos + 1);
+        }
+        return null;
+    }
+
+    /**
      * Finds the extension in the url
      * 
      * @param url The url
-     * @return The extension
+     * @return The extension, or the default extension if there is none
      */
     public String findExtension(String url) {
         int dotPos = url.lastIndexOf('.');
         int slashPos = url.lastIndexOf('/');
         if (dotPos > slashPos && dotPos > -1) {
-            return url.substring(dotPos+1);
+            return url.substring(dotPos + 1);
         }
         return defaultExtension;
     }

http://git-wip-us.apache.org/repos/asf/struts/blob/2ec3890d/plugins/rest/src/test/java/org/apache/struts2/rest/DefaultContentTypeHandlerManagerTest.java
----------------------------------------------------------------------
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/DefaultContentTypeHandlerManagerTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/DefaultContentTypeHandlerManagerTest.java
index 10f2422..7904f7d 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/DefaultContentTypeHandlerManagerTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/DefaultContentTypeHandlerManagerTest.java
@@ -5,6 +5,7 @@ import com.opensymphony.xwork2.inject.Container;
 import com.opensymphony.xwork2.inject.Scope;
 import org.apache.struts2.rest.handler.ContentTypeHandler;
 import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -64,6 +65,47 @@ public class DefaultContentTypeHandlerManagerTest extends XWorkTestCase {
         assertEquals("json", handler.getExtension());
     }
 
+    public void testObtainingHandlerForRequestByContentType() throws Exception {
+        // given
+        DefaultContentTypeHandlerManager handlerManager = new DefaultContentTypeHandlerManager();
+        handlerManager.setContainer(new DummyContainer("application/json", ""));
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setContentType("application/json;charset=UTF-8");
+        request.setRequestURI("/index");
+
+        // when
+        ContentTypeHandler handler = handlerManager.getHandlerForRequest(request);
+
+        // then
+        assertNotNull(handler);
+        assertEquals("application/json", handler.getContentType());
+        assertEquals("", handler.getExtension());
+    }
+
+    public void testObtainingHandlerForResponseByAcceptHeader() throws Exception {
+
+        // given
+        final DefaultContentTypeHandlerManager handlerManager = new DefaultContentTypeHandlerManager();
+        handlerManager.setContainer(new DummyContainer("application/json", "json"));
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setContentType("application/json;charset=UTF-8");
+        request.addHeader("accept","application/json;charset=UTF-8");
+        request.setRequestURI("/index");
+
+        final MockHttpServletResponse response = new MockHttpServletResponse();
+        response.setContentType("application/json;charset=UTF-8");
+
+        // when
+        ContentTypeHandler handler = handlerManager.getHandlerForResponse(request,response);
+
+        // then
+        assertNotNull(handler);
+        assertEquals("application/json", handler.getContentType());
+        assertEquals("json", handler.getExtension());
+    }
+
 }
 
 class DummyContainer implements Container {