You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by bl...@apache.org on 2009/10/02 03:49:04 UTC

svn commit: r820864 - in /incubator/wink/trunk/wink-server/src: main/java/org/apache/wink/server/internal/registry/ test/java/org/apache/wink/server/integration/

Author: bluk
Date: Fri Oct  2 01:49:04 2009
New Revision: 820864

URL: http://svn.apache.org/viewvc?rev=820864&view=rev
Log:
Fallback to servlet request params for form params

Thanks Mike Rheinheimer for the contribution.

See [WINK-200]

Added:
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java   (with props)
Modified:
    incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java

Modified: incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java?rev=820864&r1=820863&r2=820864&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java (original)
+++ incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java Fri Oct  2 01:49:04 2009
@@ -27,6 +27,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +52,7 @@
 import org.apache.wink.common.internal.registry.Injectable;
 import org.apache.wink.common.internal.registry.InjectableFactory;
 import org.apache.wink.common.internal.registry.ValueConvertor.ConversionException;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
 import org.apache.wink.common.internal.uri.UriEncoder;
 import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.apache.wink.common.internal.utils.StringUtils;
@@ -348,6 +350,25 @@
                                     getAnnotations(), null);
                 formParameters =
                     (MultivaluedMap<String, String>)entityParam.getValue(runtimeContext);
+                if (formParameters.isEmpty()) {
+                    // see E011 at
+                    // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
+                    // Perhaps the message body was already consumed by a
+                    // servlet filter. Let's try the servlet request parameters
+                    // instead.
+                    Map map =
+                        RuntimeContextTLS.getRuntimeContext()
+                            .getAttribute(HttpServletRequest.class).getParameterMap();
+                    // We can't easily use MultivaluedMap.putAll because we have
+                    // a map whose values are String[]
+                    // Let's iterate and call the appropriate MultivaluedMap.put
+                    // method.
+                    for (Iterator it = map.keySet().iterator(); it.hasNext();) {
+                        String key = (String)it.next();
+                        String[] value = (String[])map.get(key);
+                        formParameters.put(key, Arrays.asList(value));
+                    }
+                }
                 runtimeContext.getAttributes().put(FORM_PARAMATERS, formParameters);
             }
 
@@ -369,7 +390,8 @@
             try {
                 return getConvertor().convert(values);
             } catch (ConversionException e) {
-                // See E010 http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html:
+                // See E010
+                // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html:
                 // "400 status code should be returned if an exception is
                 // raised during @FormParam-annotated parameter construction"
                 throw new WebApplicationException(e.getCause(), Response.Status.BAD_REQUEST);

Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java?rev=820864&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java Fri Oct  2 01:49:04 2009
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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.
+ *  
+ *******************************************************************************/
+package org.apache.wink.server.integration;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.junit.Test;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+public class ServletFilterTest extends MockServletInvocationTest {
+
+    @Override
+    protected Class<?>[] getClasses() {
+        return new Class[] {TestResource.class};
+    }
+
+    @Path("/test")
+    public static class TestResource {
+        @POST
+        @Produces("text/plain")
+        public String postFoo(@FormParam("formParam") String requestSingle,
+                              @FormParam("formParamMulti") String[] requestMulti) {
+            // make sure we can still "see" the request after the filter
+            // consumed it
+            return requestSingle + "_" + requestMulti[1] + "_response";
+        }
+    }
+
+    public final class MyServletFilter implements Filter {
+
+        public void destroy() {
+            // nothing needed for test
+        }
+
+        public void init(FilterConfig arg0) throws ServletException {
+            // nothing needed for test
+        }
+
+        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+            // consume the request body
+            ServletInputStream is = request.getInputStream();
+            while (is.read() != -1) {
+                // munch munch
+            }
+            is.close();
+        }
+
+    }
+
+    @Test
+    public void testServletFilter() throws Exception {
+        MockHttpServletRequest servletRequest =
+            MockRequestConstructor.constructMockRequest("POST", "/test", MediaType.TEXT_PLAIN);
+        servletRequest.addHeader("Content-Type", MediaType.APPLICATION_FORM_URLENCODED);
+        servletRequest.setContent("formParam=single&formParamMulti=one&formParamMulti=two"
+            .getBytes());
+        servletRequest.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        servletRequest.setParameter("formParam", "single");
+        servletRequest.setParameter("formParamMulti", new String[] {"one", "two"});
+
+        // Perform servletFilter.doFilter just before HttpServlet.service is
+        // called in invoke.
+        // Honestly, having a real servlet filter here is overkill. We could
+        // have just as simply NOT
+        // set any content on the servletRequest object to simulate consumption
+        // of the request message body.
+        // In the interest of brevity, however, let's do it the right way.
+        Filter servletFilter = new MyServletFilter();
+        servletFilter.doFilter(servletRequest, null, null);
+
+        MockHttpServletResponse servletResponse = invoke(servletRequest);
+        assertEquals("single_two_response", servletResponse.getContentAsString());
+    }
+
+}

Propchange: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/integration/ServletFilterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native