You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2014/04/01 21:01:40 UTC

svn commit: r1583755 - in /tomee/tomee/trunk/server: openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/ openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ openejb-http/src/main/java/org/apache/openejb/server/httpd/ openejb-http/...

Author: rmannibucau
Date: Tue Apr  1 19:01:39 2014
New Revision: 1583755

URL: http://svn.apache.org/r1583755
Log:
TOMEE-1162 TOMEE-1161 embedded jaxrs/http fixes to support mapping and let cxf get correct data from http request

Added:
    tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingTest.java
    tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingWithNoAppPathTest.java
    tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithMappingTest.java
Modified:
    tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
    tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java
    tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RsJMXTest.java
    tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
    tomee/tomee/trunk/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java
    tomee/tomee/trunk/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java

Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java (original)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java Tue Apr  1 19:01:39 2014
@@ -69,7 +69,6 @@ import javax.naming.Context;
 import javax.servlet.ServletException;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.Application;
 import javax.xml.bind.Marshaller;
@@ -113,6 +112,7 @@ public class CxfRsHttpListener implement
     private AbstractHTTPDestination destination;
     private Server server;
     private String context = "";
+    private String servlet = "";
     private final Collection<Pattern> staticResourcesList = new CopyOnWriteArrayList<Pattern>();
     private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
 
@@ -159,8 +159,10 @@ public class CxfRsHttpListener implement
         }
 
         // fix the address (to manage multiple connectors)
-        if (httpRequest instanceof HttpRequestImpl) {
-            ((HttpRequestImpl) httpRequest).initPathFromContext(context);
+        if (HttpRequestImpl.class.isInstance(httpRequest)) {
+            final HttpRequestImpl requestImpl = HttpRequestImpl.class.cast(httpRequest);
+            requestImpl.initPathFromContext(context);
+            requestImpl.initServletPath(servlet);
         }
 
         String baseURL = BaseUrlHelper.getBaseURL(httpRequest);
@@ -175,21 +177,7 @@ public class CxfRsHttpListener implement
         final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
         Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
         try {
-            destination.invoke(null, httpRequest.getServletContext(), new HttpServletRequestWrapper(httpRequest) {
-                // see org.apache.cxf.jaxrs.utils.HttpUtils.getPathToMatch()
-                // cxf uses implicitly getRawPath() from the endpoint but not for the request URI
-                // so without stripping the address until the context the behavior is weird
-                // this is just a workaround waiting for something better
-                @Override
-                public String getRequestURI() {
-
-                    if (httpRequest instanceof HttpRequestImpl) {
-                        return strip(context, ((HttpRequestImpl) httpRequest).requestRawPath());
-                    } else {
-                        return strip(context, super.getRequestURI());
-                    }
-                }
-            }, httpResponse);
+            destination.invoke(null, httpRequest.getServletContext(), httpRequest, httpResponse);
         } finally {
             if (oldLoader != null) {
                 CxfUtil.clearBusLoader(oldLoader);
@@ -239,13 +227,6 @@ public class CxfRsHttpListener implement
 
     }
 
-    private String strip(final String context, final String requestURI) {
-        if (requestURI.startsWith(context)) {
-            return requestURI.substring(context.length());
-        }
-        return requestURI;
-    }
-
     @Override
     public void deploySingleton(final String contextRoot, final String fullContext, final Object o, final Application appInstance,
                                 final Collection<Object> additionalProviders, final ServiceConfiguration configuration) {
@@ -430,6 +411,11 @@ public class CxfRsHttpListener implement
             if (!webContext.startsWith("/")) {
                 this.context = "/" + webContext;
             }
+            final int servletIdx = 1 + this.context.substring(1).indexOf('/');
+            if (servletIdx > 0) {
+                this.servlet = this.context.substring(servletIdx);
+                this.context = this.context.substring(0, servletIdx);
+            }
             destination = (AbstractHTTPDestination) server.getDestination();
 
             final String base;

Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java (original)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java Tue Apr  1 19:01:39 2014
@@ -83,7 +83,7 @@ public class CdiInterceptorContextTest {
 
         @AroundInvoke
         public Object invoke(final InvocationContext ic) throws Exception {
-            if (ic.getMethod().getName().equals("bar") && "foo".equals(request.getRequestURI())) {
+            if (ic.getMethod().getName().equals("bar") && "/app/foo".equals(request.getRequestURI())) {
                 return "perfect";
             }
             return ic.proceed();

Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RsJMXTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RsJMXTest.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RsJMXTest.java (original)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RsJMXTest.java Tue Apr  1 19:01:39 2014
@@ -58,7 +58,7 @@ public class RsJMXTest {
         assertTrue(LocalMBeanServer.get().isRegistered(name));
 
         final String wadlXml = String.class.cast(LocalMBeanServer.get().invoke(name, "getWadl", new Object[]{null}, new String[0]));
-        assertThat(wadlXml, wadlXml, CoreMatchers.containsString("<resources base=\"http://127.0.0.1:4204/app/foo/"));
+        assertThat(wadlXml, wadlXml, CoreMatchers.containsString("<resources base=\"http://127.0.0.1:4204/app/"));
 
         /* need a fix from cxf which will be shipped soon so deactivating it ATM
         final String wadlJson = String.class.cast(LocalMBeanServer.get().invoke(name, "getWadl", new Object[]{"json"}, new String[0]));

Added: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingTest.java?rev=1583755&view=auto
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingTest.java (added)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingTest.java Tue Apr  1 19:01:39 2014
@@ -0,0 +1,81 @@
+/*
+ *     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.openejb.server.cxf.rs;
+
+import org.apache.cxf.jaxrs.client.ServerWebApplicationException;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.server.cxf.rs.beans.HookedRest;
+import org.apache.openejb.server.cxf.rs.beans.MyExpertRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyRESTApplication;
+import org.apache.openejb.server.cxf.rs.beans.MySecondRestClass;
+import org.apache.openejb.server.cxf.rs.beans.RestWithInjections;
+import org.apache.openejb.server.cxf.rs.beans.SimpleEJB;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.core.Application;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+public class SimpleApplicationWithLongMappingTest {
+    public static final String BASE_URL = "http://localhost:4204/foo/mapping/part2/my-app/";
+
+    @Module
+    @Classes(cdi = true, value = {MySecondRestClass.class, HookedRest.class, RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class})
+    public WebApp war() {
+        return new WebApp()
+                .contextRoot("foo")
+                .addServlet("REST Application", Application.class.getName())
+                .addInitParam("REST Application", "javax.ws.rs.Application", MyRESTApplication.class.getName())
+                .addServletMapping("REST Application", "/mapping/part2/*");
+    }
+
+    @Test
+    public void first() {
+        final String hi = WebClient.create(BASE_URL).path("/first/hi").get(String.class);
+        assertEquals("Hi from REST World!", hi);
+    }
+
+    @Test
+    public void second() {
+        final String hi = WebClient.create(BASE_URL).path("/second/hi2/2nd").get(String.class);
+        assertEquals("hi 2nd", hi);
+    }
+
+    @Test(expected = ServerWebApplicationException.class)
+    public void nonListed() {
+        WebClient.create(BASE_URL).path("/non-listed/yata/foo").get(String.class);
+    }
+
+    @Test
+    public void hooked() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/hooked/post").get(Boolean.class));
+    }
+
+    @Test
+    public void injectEjb() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/inject/ejb").get(Boolean.class));
+    }
+}

Added: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingWithNoAppPathTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingWithNoAppPathTest.java?rev=1583755&view=auto
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingWithNoAppPathTest.java (added)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithLongMappingWithNoAppPathTest.java Tue Apr  1 19:01:39 2014
@@ -0,0 +1,83 @@
+/*
+ *     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.openejb.server.cxf.rs;
+
+import org.apache.cxf.jaxrs.client.ServerWebApplicationException;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.server.cxf.rs.beans.HookedRest;
+import org.apache.openejb.server.cxf.rs.beans.MyExpertRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyRESTApplication;
+import org.apache.openejb.server.cxf.rs.beans.MySecondRestClass;
+import org.apache.openejb.server.cxf.rs.beans.RestWithInjections;
+import org.apache.openejb.server.cxf.rs.beans.SimpleEJB;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.core.Application;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+public class SimpleApplicationWithLongMappingWithNoAppPathTest {
+    public static final String BASE_URL = "http://localhost:4204/foo/mapping/part2/";
+
+    @Module
+    @Classes(cdi = true, value = {MySecondRestClass.class, HookedRest.class, RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class})
+    public WebApp war() {
+        return new WebApp()
+                .contextRoot("foo")
+                .addServlet("REST Application", Application.class.getName())
+                .addInitParam("REST Application", "javax.ws.rs.Application", MyRootRESTApp.class.getName())
+                .addServletMapping("REST Application", "/mapping/part2/*");
+    }
+
+    public static class MyRootRESTApp extends MyRESTApplication {}
+
+    @Test
+    public void first() {
+        final String hi = WebClient.create(BASE_URL).path("/first/hi").get(String.class);
+        assertEquals("Hi from REST World!", hi);
+    }
+
+    @Test
+    public void second() {
+        final String hi = WebClient.create(BASE_URL).path("/second/hi2/2nd").get(String.class);
+        assertEquals("hi 2nd", hi);
+    }
+
+    @Test(expected = ServerWebApplicationException.class)
+    public void nonListed() {
+        WebClient.create(BASE_URL).path("/non-listed/yata/foo").get(String.class);
+    }
+
+    @Test
+    public void hooked() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/hooked/post").get(Boolean.class));
+    }
+
+    @Test
+    public void injectEjb() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/inject/ejb").get(Boolean.class));
+    }
+}

Added: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithMappingTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithMappingTest.java?rev=1583755&view=auto
==============================================================================
--- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithMappingTest.java (added)
+++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationWithMappingTest.java Tue Apr  1 19:01:39 2014
@@ -0,0 +1,81 @@
+/*
+ *     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.openejb.server.cxf.rs;
+
+import org.apache.cxf.jaxrs.client.ServerWebApplicationException;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.server.cxf.rs.beans.HookedRest;
+import org.apache.openejb.server.cxf.rs.beans.MyExpertRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass;
+import org.apache.openejb.server.cxf.rs.beans.MyRESTApplication;
+import org.apache.openejb.server.cxf.rs.beans.MySecondRestClass;
+import org.apache.openejb.server.cxf.rs.beans.RestWithInjections;
+import org.apache.openejb.server.cxf.rs.beans.SimpleEJB;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.core.Application;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+public class SimpleApplicationWithMappingTest {
+    public static final String BASE_URL = "http://localhost:4204/foo/mapping/my-app/";
+
+    @Module
+    @Classes(cdi = true, value = {MySecondRestClass.class, HookedRest.class, RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class})
+    public WebApp war() {
+        return new WebApp()
+                .contextRoot("foo")
+                .addServlet("REST Application", Application.class.getName())
+                .addInitParam("REST Application", "javax.ws.rs.Application", MyRESTApplication.class.getName())
+                .addServletMapping("REST Application", "/mapping/*");
+    }
+
+    @Test
+    public void first() {
+        final String hi = WebClient.create(BASE_URL).path("/first/hi").get(String.class);
+        assertEquals("Hi from REST World!", hi);
+    }
+
+    @Test
+    public void second() {
+        final String hi = WebClient.create(BASE_URL).path("/second/hi2/2nd").get(String.class);
+        assertEquals("hi 2nd", hi);
+    }
+
+    @Test(expected = ServerWebApplicationException.class)
+    public void nonListed() {
+        WebClient.create(BASE_URL).path("/non-listed/yata/foo").get(String.class);
+    }
+
+    @Test
+    public void hooked() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/hooked/post").get(Boolean.class));
+    }
+
+    @Test
+    public void injectEjb() {
+        assertEquals(true, WebClient.create(BASE_URL).path("/inject/ejb").get(Boolean.class));
+    }
+}

Modified: tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java (original)
+++ tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java Tue Apr  1 19:01:39 2014
@@ -144,6 +144,7 @@ public class HttpRequestImpl implements 
     private String encoding = "UTF-8";
     private ServletContext context = null;
     private String contextPath = "";
+    private String servletPath = null;
 
     public HttpRequestImpl(URI socketURI) {
         this.socketURI = socketURI;
@@ -222,6 +223,9 @@ public class HttpRequestImpl implements 
 
     @Override
     public String getPathInfo() {
+        if (servletPath != null) {
+            return path.substring(servletPath.length());
+        }
         return path;
     }
 
@@ -258,7 +262,7 @@ public class HttpRequestImpl implements 
 
     @Override
     public String getRequestURI() {
-        return getURI().toString();
+        return getURI().getRawPath();
     }
 
     @Override
@@ -268,9 +272,16 @@ public class HttpRequestImpl implements 
 
     @Override
     public String getServletPath() {
+        if (servletPath != null) {
+            return servletPath;
+        }
         return getPathInfo();
     }
 
+    public void initServletPath(final String servlet) {
+        servletPath = servlet;
+    }
+
     /**
      * Gets the URI for the current URL page.
      *

Modified: tomee/tomee/trunk/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java (original)
+++ tomee/tomee/trunk/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java Tue Apr  1 19:01:39 2014
@@ -56,7 +56,7 @@ public class FilterRegistrationTest {
 
     @Test
     public void touch() throws IOException {
-        assertEquals("http://ok/filter/touch", IO.slurp(new URL("http://localhost:4204/filter/touch")));
+        assertEquals("/filter/touch", IO.slurp(new URL("http://localhost:4204/filter/touch")));
         assertTrue(TestFilter.init);
         assertTrue(TestFilter.ok);
         assertTrue(TestFilter2.ok);

Modified: tomee/tomee/trunk/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java?rev=1583755&r1=1583754&r2=1583755&view=diff
==============================================================================
--- tomee/tomee/trunk/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java (original)
+++ tomee/tomee/trunk/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java Tue Apr  1 19:01:39 2014
@@ -467,15 +467,7 @@ public abstract class RESTService implem
     }
 
     private static String appPrefix(final WebAppInfo info, final Class<?> appClazz) {
-        final ApplicationPath path = appClazz.getAnnotation(ApplicationPath.class);
-        if (path != null) {
-            final String appPath = path.value();
-            if (appPath.startsWith("/")) {
-                return appPath.substring(1);
-            } else {
-                return appPath;
-            }
-        }
+        StringBuilder builder = null;
 
         // no annotation, try servlets
         for (final ServletInfo s : info.servlets) {
@@ -504,11 +496,35 @@ public abstract class RESTService implem
                 if (mapping.startsWith("/")) {
                     mapping = mapping.substring(1);
                 }
-                return mapping;
+
+                builder = new StringBuilder();
+                builder.append(mapping);
+                break;
+            }
+        }
+
+        // annotation
+        final ApplicationPath path = appClazz.getAnnotation(ApplicationPath.class);
+        if (path != null) {
+            final String appPath = path.value();
+
+            if (builder == null) {
+                builder = new StringBuilder();
+            } else if (builder.length() > 0 && builder.charAt(builder.length() - 1) != '/') {
+                builder.append('/');
+            }
+
+            if (appPath.startsWith("/")) {
+                builder.append(appPath.substring(1));
+            } else {
+                builder.append(appPath);
             }
         }
 
-        return null;
+        if (builder == null) {
+            return null;
+        }
+        return builder.toString();
     }
 
     private static <T> boolean isProvider(final Class<T> clazz) {
@@ -860,7 +876,7 @@ public abstract class RESTService implem
         HttpListener listener = rsRegistry.removeListener(context);
         if (listener != null) {
 
-            if(BasicAuthHttpListenerWrapper.class.isInstance(listener)){
+            if (BasicAuthHttpListenerWrapper.class.isInstance(listener)) {
                 listener = BasicAuthHttpListenerWrapper.class.cast(listener).getHttpListener();
             }