Hi,
It was politely pointed out to me that what i wrote was a bit too much
of a brain dump. So what follows below is a second try with a specific
proposal that is hopefully clearer and more precise.
Paul.
Template structure layout
-------------------------
<context>/
foo/
Foo/
super.jsp # an inheritable template
override.jsp
bar/
BarResource/
index.jsp
item.jsp
create.jsp
baz/
BazResource/
static.html # a static file
override.jsp # overrides that in foo/Foo/
Classes
-------
package foo;
public class Foo { ... }
package bar;
@Path("bar") public class BarResource extends foo.Foo {
@Path("{id}") @GET public Viewable item(
@PathParam("id") String id) {
String model = ...;
return new Viewable("item", model);
}
@POST public Response create() {
URI cu = ...
Viewable v = new Viewable("create", this);
return Response.created(u).entity(v).build();
}
}
package baz;
@Path("baz") public class BazResource extends foo.Foo {
@GET public String get() {
return "content";
}
}
Request Template Model
------------------------------------------------------------------------
GET /bar /bar/BarResource/index.jsp instance of BarResource
GET /bar/1 /bar/BarResource/item.jsp instance of String created
by BarResource.item
GET /bar/super " "
GET /bar/index " "
GET /bar/item " "
GET /bar/create " "
POST /bar /bar/BarResource/create.jsp instance of BarResource
returned by
BarResource.create
GET /baz N/A N/A specific content is
returned
GET /baz/ N/A N/A the static file is
static.html returned
GET /baz/super /foo/Foo/super.jsp instance of BazResource
GET /baz/ /bar/Baz/override.jsp instance of BazResource
override
Rules
-----
- The directory path of templates and static files for a resource class
is specified by the fully qualified name of that class converted to a
path.
- A template, "xxxx.yyyy", consists of a template name "xxxx" and
template meta-data "yyyy", where "yyyy" describes the template
technology and potentially the media type and language.
- A resource class will inherit the templates and static files from the
direct and indirect super classes. A class can override the templates
or static files of a direct or indirect super class.
- If a request URI path matches a HTTP method on a resource then that
method is processed. An HTTP method takes precedence over matching of
template and static files associated with a resource.
- A HTTP method may return a Viewable object that contains the
template name to use and the instance of the model passed to the
template.
- If a request URI path does not match any HTTP methods but matches the
template name of a template associated with the resource class then
that template is selected and the model is the instance of the
resource class.
- If a request URI path does not match any HTTP methods or templates
but matches a static file associated with the resource class then that
static file is returned.
- If a request URI path does not match a HTTP method, template or static
file a 404 is returned.
Questions/thoughts
------------------
- Should static files take precedence over HTTP methods?
- Should one use an annotation on the HTTP method to specify the
template name?
@Viewable("item")
@Path("{id}") @GET public String show(
@PathParam("id") String id) {
String model = ...;
return model;
}
Paul Sandoz wrote:
> Hi,
>
> Below are some ideas on MVC support for Jersey. Sorry about the length.
> I wanted to 'save' my ideas as well as giving people an opportunity to
> comment and contribute if they so wish before i start diving in and
> developing.
>
> Paul.
>
> Implicit use of templates with resource class as model
> ------------------------------------------------------
>
> Given a class:
>
> foo.Resource
>
> And a template:
>
> <context>/foo/Resource/abc.jsp
>
> If the request path matches "abc" and is an HTTP GET request then the
> instance of foo.Resource will be passed to the template "abc.jsp" to
> produce the response.
>
> In general there can be a URI rule on a resource class that occurs first
> for matching:
>
> (<expression for path segment>?)(/)?
>
> The rule is accepted if:
>
> 1) the matching path segment is empty, there is an 'index' template and
> there is no @GET method implemented on the associated resource class;
>
> 2) the matching path segment is non-empty, and the encoded characters of
> that segment match a template with the same name, and there is no
> @GET method with an @Path value that has the same name as the
> template; or
>
> 3) the matching path segment matches a static resource of the same name.
>
>
> Explicit use of templates with resource class returning a model
> ---------------------------------------------------------------
>
> If there is a GET method on foo resource
>
> @GET
> Model get() { ... }
>
> and there is a template:
>
> <context>/foo/Resource/index.jsp
>
> Then the Model instance is the input to the template index.jsp
>
> If there is a GET method on foo resource
>
> @GET
> @Path("abc")
> Model getAbc() { ... }
>
> and there is a template:
>
> <context>/foo/Resource/abc.jsp
>
> Then the Model instance is the input to the template abc.jsp
>
> If there is a GET method on foo resource
>
> @GET
> @Path("abc/{id}")
> Model getAbc() { ... }
>
> and there is a template:
>
> <context>/foo/Resource/abc%2F{id}.jsp
>
> Then Model is the input to the template abc%2F{id}.jsp
>
> This is a little odd. It sort of breaks the hierarchical model. This
> path will not be matched by the implicit URI rule.
>
> The existence of such templates can be verified at initiation time and
> can be input into the implicit approach to determine acceptance.
>
> If a GET method has a template associated with it then it returns a
> model that is passed to the template for processing.
>
>
> Template inheritance
> --------------------
>
> If there are classes:
>
> @Path("foo")
> class foo.Resource
>
> @Path("bar")
> class bar.Resource extends foo.Resource { ... }
>
> And templates:
>
> <context>/foo/Resource/abc.jsp
>
> <context>/foo/Resource/xyz.jsp
>
> Then class bar.Resource will inherit templates from foo.Resource unless
> it overrides them. So a path "bar/abc" will match the template abc.jsp
> and use the model that is an instance of bar.Resource.
>
>
> Choice of template name
> -----------------------
>
> @Path("foo")
> @Template("welcome")
> class foo.Resource {
>
> @GET String get() { ... }
>
> @GET @Path("abc") @Template("xyz") String getAbc() { ... }
>
> }
>
> A path matching "foo" would pass the String instance returned from the
> "get" method to the template "<context>/foo/welcome".
>
> A path matching "foo/abc" would pass the String instance returned from
> the "getAbc" method to the template "<context>/foo/xyz".
>
>
> Templates for other HTTP methods
> --------------------------------
>
> @Path("foo")
> class foo.Resource {
>
> @POST @Template("post") String post() { ... }
>
> }
>
> A path matching "foo" with the HTTP method POST would pass the String
> instance returned from the "post" method to the template
> "<context>/foo/post".
>
> It seems appropriate to support implicit use of templates for only GET
> methods i.e. since JAX-RS separates out HTTP methods the same should be
> encouraged for templates.
>
>
> Programmatic use
> ----------------
>
> @Path("foo")
> class foo.Resource {
>
> @HttpContext TemplateContext context;
>
> @GET Response get() {
> String m = ...
> return context.forwardTo("welcome", m);
> }
>
> }
>
> A path matching "foo" with the HTTP method GET would obtain a String
> instance "m" as the model and obtain a response from the TemplateContext
> instance that represents a response to forward "m" to the template
> "<context>/foo/welcome".
>
> Alternatively we can use a specific Java type:
>
> @Path("foo")
> class foo.Resource {
>
> @GET Viewable get() {
> String m = ...
> return new Viewable("welcome", m);
> }
>
> }
>
> or:
>
> @Path("foo")
> class foo.Resource {
>
> @GET Viewable get() {
> String m = ...
> return new Viewable(m);
> }
>
> }
>
> In the latter case the template is implicitly determined. A Response
> builder can be used with Viewable as well. I think i prefer the Viewable
> instance approach. There will be a message body writer for the Viewable
> type. This writer will defer to template implementations themselves that
> are an extension of message body writer.
>
>
> Issues/TODO
> -----------
>
> If using the non-programmatic approach should template support always be
> explicit using the @Template annotation (it does not have to have a
> value by default) ? Then the behavior of the resource classes will be
> consistent rather than behaving differently if templates are present or
> not. I think i prefer that the programmatic approach always be used for
> HTTP resource methods and the non-annotated implicit approach takes
> lesser precedence that the former and works for paths that don't match
> the paths on HTTP resource methods and only works for HTTP GET.
>
> Registration of template implementations. Use @Provider.
>
> Support for localization, for example templates for French, Spanish and
> English, or a properties mechanism for one template with translated
> property files.
>
> Support for content types, for example templates returning XML, HTML
> etc. based on client accept header.
>
>
--
| ? + ? = To question
----------------\
Paul Sandoz
x38109
+33-4-76188109