You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/06/24 16:05:50 UTC

svn commit: r788030 - in /cxf/trunk: rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/ systests/src/test/java/org/apache/cxf/systest/jaxrs/ systests/src/test/java/org/a...

Author: sergeyb
Date: Wed Jun 24 14:05:50 2009
New Revision: 788030

URL: http://svn.apache.org/viewvc?rev=788030&view=rev
Log:
Updating AbstractCxfServlet to support arbitrary HTTP methods

Added:
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt   (with props)
Modified:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java?rev=788030&r1=788029&r2=788030&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractCXFServlet.java Wed Jun 24 14:05:50 2009
@@ -20,12 +20,16 @@
 
 import java.io.IOException;
 import java.lang.ref.WeakReference;
+import java.util.Arrays;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -40,9 +44,16 @@
 
 
 public abstract class AbstractCXFServlet extends HttpServlet {
+    
     static final Map<String, WeakReference<Bus>> BUS_MAP = new Hashtable<String, WeakReference<Bus>>();
     static final Logger LOG = getLogger();
     
+    /**
+     * List of well-known HTTP 1.1 verbs, with POST and GET being the most used verbs at the top 
+     */
+    private static final List<String> KNOWN_HTTP_VERBS = 
+        Arrays.asList(new String[]{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE"});
+    
     protected Bus bus;
     protected ServletTransportFactory servletTransportFactory;
     protected ServletController controller;
@@ -137,11 +148,13 @@
         bus.shutdown(true);
     }
     
-    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
+        throws ServletException {
         invoke(request, response);
     }
 
-    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
+        throws ServletException {
         invoke(request, response);
     }
 
@@ -152,12 +165,56 @@
     }
 
     @Override
-    protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException,
-        IOException {
+    protected void doPut(HttpServletRequest request, HttpServletResponse response) 
+        throws ServletException, IOException {
+        invoke(request, response);
+    }
+    
+    @Override
+    protected void doHead(HttpServletRequest request, HttpServletResponse response) 
+        throws ServletException, IOException {
+        invoke(request, response);
+    }
+    
+    @Override
+    protected void doOptions(HttpServletRequest request, HttpServletResponse response) 
+        throws ServletException, IOException {
         invoke(request, response);
     }
     
-    private  void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+    
+    
+    /**
+     * {@inheritDoc}
+     * 
+     * javax.http.servlet.HttpServlet does not let to override the code which deals with
+     * unrecognized HTTP verbs such as PATCH (being standardized), WebDav ones, etc.
+     * Thus we let CXF servlets process unrecognized HTTP verbs directly, otherwise we delegate
+     * to HttpService  
+     */
+    @Override
+    public void service(ServletRequest req, ServletResponse res)
+        throws ServletException, IOException {
+        
+        HttpServletRequest      request;
+        HttpServletResponse     response;
+        
+        try {
+            request = (HttpServletRequest) req;
+            response = (HttpServletResponse) res;
+        } catch (ClassCastException e) {
+            throw new ServletException("Unrecognized HTTP request or response object");
+        }
+        
+        String method = request.getMethod();
+        if (KNOWN_HTTP_VERBS.contains(method)) {
+            super.service(request, response);
+        } else {
+            invoke(request, response);
+        }
+    }
+    
+    protected void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException {
         try {
             BusFactory.setThreadDefaultBus(getBus());
             controller.invoke(request, response);

Added: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java?rev=788030&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java (added)
+++ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java Wed Jun 24 14:05:50 2009
@@ -0,0 +1,163 @@
+/**
+ * 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.cxf.transport.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.easymock.classextension.EasyMock;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AbstractCXFServletTest extends Assert {
+
+    @Test
+    public void testPost() throws Exception {
+        testHttpMethod("POST");
+    }
+    
+    @Test
+    public void testGet() throws Exception {
+        testHttpMethod("GET");
+    }
+    
+    @Test
+    public void testPut() throws Exception {
+        testHttpMethod("PUT");
+    }
+    
+    @Test
+    public void testDelete() throws Exception {
+        testHttpMethod("DELETE");
+    }
+    
+    @Test
+    public void testHead() throws Exception {
+        testHttpMethod("HEAD");
+    }
+    
+    @Test
+    public void testOptions() throws Exception {
+        testHttpMethod("OPTIONS");
+    }
+    
+    @Test
+    public void testPatch() throws Exception {
+        testHttpMethod("PATCH", true);
+    }
+    
+    private void testHttpMethod(String method) throws Exception {
+        testHttpMethod(method, false);
+    }
+    
+    private void testHttpMethod(String method, boolean setMethod) throws Exception {
+        TestServlet servlet = new TestServlet();
+        if (setMethod) {
+            servlet.setMethod(method);
+        }
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        HttpServletResponse res = EasyMock.createMock(HttpServletResponse.class);
+        
+        req.getMethod();
+        EasyMock.expectLastCall().andReturn(method).times(3);
+        EasyMock.replay(req);
+        
+        servlet.service(req, res);
+        assertTrue(servlet.isInvoked());
+        assertEquals(method, servlet.getMethod());
+    }
+    
+    private static class TestServlet extends AbstractCXFServlet {
+
+        private boolean invoked;
+        private String method;
+        @Override
+        public void loadBus(ServletConfig servletConfig) throws ServletException {
+        }
+        
+        @Override
+        protected void doPost(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException {
+            method = "POST";
+            super.doPost(request, response);
+        }
+        
+        @Override
+        protected void doGet(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException {
+            method = "GET";
+            super.doGet(request, response);
+        }
+        
+        @Override
+        protected void doPut(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException, IOException {
+            method = "PUT";
+            super.doPut(request, response);
+        }
+        
+        @Override
+        protected void doDelete(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException, IOException {
+            method = "DELETE";
+            super.doDelete(request, response);
+        }
+        
+        @Override
+        protected void doHead(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException, IOException {
+            method = "HEAD";
+            super.doHead(request, response);
+        }
+        
+        @Override
+        protected void doOptions(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException, IOException {
+            method = "OPTIONS";
+            super.doOptions(request, response);
+        }
+        
+        @Override
+        protected void invoke(HttpServletRequest request, HttpServletResponse response) 
+            throws ServletException {
+            assertEquals(method, request.getMethod());
+            invoked = true;    
+        }
+        
+        public boolean isInvoked() {
+            return invoked;
+        }
+        
+        public String getMethod() {
+            return method;
+        }
+        
+        public void setMethod(String m) {
+            method = m;
+        }
+        
+    }
+    
+}

Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/servlet/AbstractCXFServletTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=788030&r1=788029&r2=788030&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Wed Jun 24 14:05:50 2009
@@ -129,7 +129,7 @@
     
     @RETRIEVE
     @Path("books/aegis/retrieve")
-    @Produces({"application/html;q=1.0", "application/xml;q=0.5", "application/json;q=0.5" })
+    @Produces({"application/html;q=0.5", "application/xml;q=1.0", "application/json;q=0.5" })
     public Book getBookAegisRetrieve() {
         return getBookAegis();
     }

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=788030&r1=788029&r2=788030&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Wed Jun 24 14:05:50 2009
@@ -19,8 +19,11 @@
 
 package org.apache.cxf.systest.jaxrs;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.Socket;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.HashMap;
@@ -31,7 +34,6 @@
 
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.methods.FileRequestEntity;
-import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.cxf.helpers.IOUtils;
@@ -232,20 +234,29 @@
     }
     
     @Test
-    @Ignore
     public void testRetrieveBookAegis3() throws Exception {
-        GetMethod get = new GetMethod("http://localhost:9080/the/thebooks4/bookstore/books/aegis/retrieve");
-        get.setRequestHeader("Content-Type", "*/*");
-        get.setRequestHeader("Accept", "application/xml");
-        HttpClient httpClient = new HttpClient();
-        try {
-            httpClient.executeMethod(get);           
-            String aegisData = getStringFromInputStream(get.getResponseBodyAsStream());
-            InputStream expected = getClass().getResourceAsStream("resources/expected_add_book_aegis.txt");
-            assertEquals(getStringFromInputStream(expected), aegisData);
-        } finally {
-            get.releaseConnection();
+        
+        Socket s = new Socket("localhost", 9080);
+        
+        InputStream is = this.getClass().getResourceAsStream("resources/retrieveRequest.txt");
+        byte[] bytes = IOUtils.readBytesFromStream(is);
+        s.getOutputStream().write(bytes);
+        s.getOutputStream().flush();
+        
+        BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
+        StringBuilder sb = new StringBuilder();
+        String str = null;
+        while ((str = r.readLine()) != null) {
+            sb.append(str);
         }
+        
+        String aegisData = sb.toString();
+        s.getInputStream().close();
+        s.close();
+        String expected = getStringFromInputStream(
+                              getClass().getResourceAsStream("resources/expected_add_book_aegis.txt"));
+        assertTrue(aegisData.contains(expected));
+        
     }
     
     @Test

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt?rev=788030&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt Wed Jun 24 14:05:50 2009
@@ -0,0 +1,7 @@
+RETRIEVE /the/thebooks4/bookstore/books/aegis/retrieve HTTP/1.1
+Content-Type: */*
+Accept: application/xml
+User-Agent: Java/1.5.0_12
+Host: localhost:9080
+Connection: close
+

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/retrieveRequest.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain