[seam-commits] Seam SVN: r11429 - in branches/community/Seam_2_2: examples/restbay/src/org/jboss/seam/example/restbay and 1 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed Aug 26 06:35:21 EDT 2009


Author: christian.bauer at jboss.com
Date: 2009-08-26 06:35:20 -0400 (Wed, 26 Aug 2009)
New Revision: 11429

Modified:
   branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Webservices.xml
   branches/community/Seam_2_2/examples/restbay/src/org/jboss/seam/example/restbay/AuctionService.java
   branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
   branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
   branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/resteasy-2.2.xsd
Log:
JBSEAM-4360, fixed REST URI base path extraction

Modified: branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Webservices.xml
===================================================================
--- branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Webservices.xml	2009-08-26 08:05:50 UTC (rev 11428)
+++ branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Webservices.xml	2009-08-26 10:35:20 UTC (rev 11429)
@@ -242,11 +242,17 @@
          </para>
 
          <itemizedlist>
+             <listitem>
+                <para>
+                   The URI starts with the host and context path of your application,
+                    e.g. <literal>http://your.hostname/myapp</literal>.
+                </para>
+             </listitem>
             <listitem>
                <para>
-                  The URI starts with the pattern mapped in <literal>web.xml</literal> for the
-                  <literal>SeamResourceServlet</literal>, e.g <literal>/seam/resource</literal> if you follow
-                  the common examples. Change this setting to expose your RESTful resources under a different base.
+                  Then the pattern mapped in <literal>web.xml</literal> for the <literal>SeamResourceServlet</literal>,
+                   e.g <literal>/seam/resource</literal> if you follow the common examples, is appended.
+                  Change this setting to expose your RESTful resources under a different base.
                   Note that this is a global change and other Seam resources (e.g. <literal>s:graphicImage</literal>)
                   are then also served under that base path.
                </para>
@@ -255,23 +261,23 @@
                <para>
                   The RESTEasy integration for Seam then appends a configurable string to the base path, by default
                   this is <literal>/rest</literal>. Hence, the full base path of your resources would e.g. be
-                  <literal>/seam/resource/rest</literal>. We recommend that you change this string in your application,
+                  <literal>/myapp/seam/resource/rest</literal>. We recommend that you change this string in your application,
                   you could for example add a version number to prepare for a future REST API upgrade of your services
-                  (old clients would keep the old URI base): <literal>/seam/resource/restv1</literal>.
+                  (old clients would keep the old URI base): <literal>/myapp/seam/resource/restv1</literal>.
                </para>
             </listitem>
             <listitem>
                <para>
                   Finally, the actual resource is available under the defined <literal>@Path</literal>, e.g. a resource
                   mapped with <literal>@Path("/customer")</literal> would be available under
-                  <literal>/seam/resource/rest/customer</literal>.
+                  <literal>/myapp/seam/resource/rest/customer</literal>.
                </para>
             </listitem>
          </itemizedlist>
 
          <para>
             As an example, the following resource definition would return a plaintext representation for any
-            GET requests using the URI <literal>http://your.hostname/seam/resource/rest/customer/123</literal>:
+            GET requests using the URI <literal>http://your.hostname/myapp/seam/resource/rest/customer/123</literal>:
          </para>
 
          <programlisting role="JAVA"><![CDATA[@Path("/customer")
@@ -309,24 +315,12 @@
          <programlisting role="XML"><![CDATA[<resteasy:application resource-path-prefix="/restv1"/>]]></programlisting>
 
          <para>
-            The full base path to your resources is now <literal>/seam/resource/restv1/{resource}</literal> - note
+            The full base path to your resources is now <literal>/myapp/seam/resource/restv1/{resource}</literal> - note
             that your <literal>@Path</literal> definitions and mappings do NOT change. This is an application-wide
-            switch usually used for versioning of the HTTP API.
+            switch usually used for versioning of the HTTP interface.
          </para>
 
          <para>
-            You can disable stripping of the base path if you'd like to map the full path in your resources:
-         </para>
-
-         <programlisting role="XML"><![CDATA[<resteasy:application strip-seam-resource-path="false"/>]]></programlisting>
-
-         <para>
-            The path of a resource is now mapped with e.g.
-            <literal>@Path("/seam/resource/rest/customer")</literal>. We do not recommend disabling this feature,
-            as your resource class mappings are then bound to a particular deployment scenario.
-         </para>
-
-         <para>
             Seam will scan your classpath for any deployed <literal>@javax.ws.rs.Path</literal> resources and any
             <literal>@javax.ws.rs.ext.Provider</literal> classes. You can disable scanning and configure these
             classes manually:
@@ -362,9 +356,10 @@
             as shown above. Note that you have to annotate the <literal>@Local</literal> interface of the EJB with
             <literal>@Path</literal>, <literal>@GET</literal>, and so on - not the bean implementation class. This allows
             you to keep your application deployment-portable with the global Seam <literal>jndi-pattern</literal> switch
-            on <literal>&lt;core:init/&gt;</literal>. Note that EJB resources will not be found even if scanning of
-            resources is enabled, you always have to list them manually. Again, this is only relevant for EJB resources
-            that are not also Seam components and that do not have a <literal>@Name</literal> annotation.
+            on <literal>&lt;core:init/&gt;</literal>. Note that plain (non-Seam component) EJB resources will not be found
+            even if scanning of resources is enabled, you always have to list them manually. Again, this whole paragraph
+            is only relevant for EJB resources that are not also Seam components and that do not have
+            an <literal>@Name</literal> annotation.
          </para>
 
          <para>

Modified: branches/community/Seam_2_2/examples/restbay/src/org/jboss/seam/example/restbay/AuctionService.java
===================================================================
--- branches/community/Seam_2_2/examples/restbay/src/org/jboss/seam/example/restbay/AuctionService.java	2009-08-26 08:05:50 UTC (rev 11428)
+++ branches/community/Seam_2_2/examples/restbay/src/org/jboss/seam/example/restbay/AuctionService.java	2009-08-26 10:35:20 UTC (rev 11429)
@@ -1,18 +1,18 @@
 package org.jboss.seam.example.restbay;
 
+import org.jboss.seam.annotations.In;
 import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.util.Reflections;
 
-import javax.ws.rs.*;
+import javax.persistence.EntityManager;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
-import javax.persistence.EntityManager;
-import java.util.GregorianCalendar;
+import java.net.URI;
 import java.util.List;
-import java.lang.reflect.Field;
 
 /**
  * @author Christian Bauer
@@ -39,6 +39,12 @@
    @Produces("text/plain")
    public String getAuctions()
    {
+
+      URI builtURI = uriInfo.getAbsolutePathBuilder().path("3").build();
+      // We can't test for /<context> prefix here, as we don't have a context in unit tests but we
+      // have it when the application is deployed... so use endsWith()
+      assert builtURI.getPath().endsWith("/seam/resource/restv1/auction/3");
+
       // This is supposed to test field and setter injection for @Context
       assert uriInfo.getPath().equals("/auction");
       assert headers.getAcceptableMediaTypes().size() == 1;

Modified: branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
===================================================================
--- branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java	2009-08-26 08:05:50 UTC (rev 11428)
+++ branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java	2009-08-26 10:35:20 UTC (rev 11429)
@@ -415,8 +415,12 @@
       // We can always instantiate this safely here because it can't have dependencies!
       AbstractResource instance = (AbstractResource) seamComponent.newInstance();
       String path = instance.getPath();
-      if (instance.getPath() != null)
+      if (path != null)
       {
+         if (!path.startsWith("/")) {
+            path = "/" + path;
+         }
+
          log.debug(
                "registering resource, configured ResourceHome/Query on path {1}, as Seam component: {0}",
                seamComponent.getName(),

Modified: branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
===================================================================
--- branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java	2009-08-26 08:05:50 UTC (rev 11428)
+++ branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java	2009-08-26 10:35:20 UTC (rev 11429)
@@ -83,7 +83,8 @@
       // No injection, so lookup on first request
       dispatcher = (Dispatcher) Component.getInstance("org.jboss.seam.resteasy.dispatcher");
       application = (Application) Component.getInstance(Application.class);
-      if (dispatcher == null) {
+      if (dispatcher == null)
+      {
          throw new IllegalStateException(
                "ReasteasyDispatcher not available, make sure RESTEasy and all required JARs are on your classpath"
          );
@@ -125,7 +126,7 @@
             {
 
                HttpHeaders headers = ServletUtil.extractHttpHeaders(request);
-               UriInfoImpl uriInfo = extractUriInfo(request);
+               UriInfoImpl uriInfo = extractUriInfo(request, application.getResourcePathPrefix());
 
                HttpResponse theResponse = new HttpServletResponseWrapper(
                      response,
@@ -165,50 +166,34 @@
       }
    }
 
-   // Replaces the static ServletUtil.extractUriInfo(), removes the Seam-related sub-path
-   protected UriInfoImpl extractUriInfo(HttpServletRequest request)
+   protected UriInfoImpl extractUriInfo(HttpServletRequest request, String pathPrefix)
    {
-      String contextPath = request.getContextPath();
-      URI absolutePath;
       try
       {
-         URL absolute = new URL(request.getRequestURL().toString());
+         // Append a slash if there isn't one
+         if (!pathPrefix.startsWith("/")) {
+            pathPrefix = "/" + pathPrefix;
+         }
 
-         UriBuilderImpl builder = new UriBuilderImpl();
-         builder.scheme(absolute.getProtocol());
-         builder.host(absolute.getHost());
-         builder.port(absolute.getPort());
-         builder.path(absolute.getPath());
-         builder.replaceQuery(absolute.getQuery());
-         absolutePath = builder.build();
+         // Get the full path of the current request
+         URL requestURL = new URL(request.getRequestURL().toString());
+         String requestPath = requestURL.getPath();
+
+         // Find the 'servlet mapping prefix' for RESTEasy (in our case: /seam/resource/rest)
+         String mappingPrefix =
+            requestPath.substring(0, requestPath.indexOf(pathPrefix)+pathPrefix.length());
+
+         // Still is /<context>/seam/resource/rest, so cut off the context
+         mappingPrefix = mappingPrefix.substring(request.getContextPath().length());
+         
+         log.debug("Using request mapping prefix: " + mappingPrefix);
+
+         // This is the prefix used by RESTEasy to resolve resources and generate URIs with
+         return ServletUtil.extractUriInfo(request, mappingPrefix);
       }
       catch (MalformedURLException e)
       {
          throw new RuntimeException(e);
       }
-
-      String path = PathHelper.getEncodedPathInfo(absolutePath.getRawPath(), contextPath);
-
-      if (application.isStripSeamResourcePath())
-      {
-         log.debug("removing SeamResourceServlet url-pattern and dispatcher prefix from request path");
-         path = path.substring(path.indexOf(getResourcePath()) + getResourcePath().length());
-      }
-
-      List<PathSegment> pathSegments = PathSegmentImpl.parseSegments(path);
-      URI baseURI = absolutePath;
-      if (!path.trim().equals(""))
-      {
-         String tmpContextPath = contextPath;
-         if (!tmpContextPath.endsWith("/")) tmpContextPath += "/";
-         baseURI = UriBuilder.fromUri(absolutePath).replacePath(tmpContextPath).build();
-      }
-
-      log.debug("UriInfo, absolute URI       : " + absolutePath);
-      log.debug("UriInfo, base URI           : " + baseURI);
-      log.debug("UriInfo, relative path/@Path: " + path);
-      log.debug("UriInfo, query string       : " + request.getQueryString());
-
-      return new UriInfoImpl(absolutePath, baseURI, path, request.getQueryString(), pathSegments);
    }
 }

Modified: branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/resteasy-2.2.xsd
===================================================================
--- branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/resteasy-2.2.xsd	2009-08-26 08:05:50 UTC (rev 11428)
+++ branches/community/Seam_2_2/src/resteasy/org/jboss/seam/resteasy/resteasy-2.2.xsd	2009-08-26 10:35:20 UTC (rev 11429)
@@ -126,10 +126,7 @@
       <xs:attribute name="strip-seam-resource-path" type="components:boolean">
           <xs:annotation>
               <xs:documentation>
-                 Remove the "/&lt;url-pattern-of-seam-resource-servlet&gt;/&lt;resource-path-prefix&gt;" part
-                 of the  request path before the request is mapped to a @Path resource. If disabled,
-                 all @Path definitions must use the full prefix of the SeamResourceServlet as 
-                 mapped with the url-pattern in  web.xml, plus the resourcePathPrefix.
+                  (DEPRECATED) Has no effect, remove from configuration.
               </xs:documentation>
           </xs:annotation>
       </xs:attribute>



More information about the seam-commits mailing list