Using MetadataService to specify the default media type

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Using MetadataService to specify the default media type

j.wismar

Hi, all-

 

(Using Restlet JEE 2.1 RC, Java 7, Tomcat7.)

 

I am writing a new service, and want to serve both a JSON and an XML version of my representations. I therefore have a @Get(“json”) handler and a @Get(“xml”) handler for each Resource.  I have also enabled the extensions tunnel in my TunnelService, and this seems to be working without any difficulty. URLs that end with .json are retrieving the JSON representation, and URLs that end with .xml are retrieving the XML representation.

 

Here’s the problem I’m having:  If a URL is specified without a file extension, I want the service to default to sending the JSON representation. When the service is starting up, I used the MetadataService and specified that the default Media Type should be MediaType.APPLICATION_JSON. Despite this, the XML representation is being returned, and I can’t figure out why.

 

I used the MetadataService in a prior project to do exactly the same thing, and it worked without a problem. (That older project used Restlet JEE 2.0, Java6 and Tomcat 6, if that’s relevant.)

 

What could I be overlooking?

 

Thanks for your help!

 

--------------------------

John Wismar

Alldata Technology

916-478-3296

 

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Using MetadataService to specify the default media type

jlouvel
Administrator

Hi John,

 

The proper/standard way in HTTP to do this is to correctly set the preferences of your clients (via the “Accept” header typically)… Otherwise, the order of the annotated methods declaration might be taken into account by Restlet when deciding how to dispatch the method call, but I wouldn’t say it is a safe bet to solely rely on this default behavior.

 

You could customize the ConnegService attached to your parent application to force the variant when client preferences are not explicitly given (MediaType.ALL), or plug a custom filter in the routing chain to enforce your policy.

 

Best regards,

Jerome

--

http://www.restlet.org

http://twitter.com/#!/jlouvel

 

 

De : John Wismar [mailto:[hidden email]]
Envoyé : mercredi 18 janvier 2012 19:11
À : [hidden email]
Objet : Using MetadataService to specify the default media type

 

Hi, all-

 

(Using Restlet JEE 2.1 RC, Java 7, Tomcat7.)

 

I am writing a new service, and want to serve both a JSON and an XML version of my representations. I therefore have a @Get(“json”) handler and a @Get(“xml”) handler for each Resource.  I have also enabled the extensions tunnel in my TunnelService, and this seems to be working without any difficulty. URLs that end with .json are retrieving the JSON representation, and URLs that end with .xml are retrieving the XML representation.

 

Here’s the problem I’m having:  If a URL is specified without a file extension, I want the service to default to sending the JSON representation. When the service is starting up, I used the MetadataService and specified that the default Media Type should be MediaType.APPLICATION_JSON. Despite this, the XML representation is being returned, and I can’t figure out why.

 

I used the MetadataService in a prior project to do exactly the same thing, and it worked without a problem. (That older project used Restlet JEE 2.0, Java6 and Tomcat 6, if that’s relevant.)

 

What could I be overlooking?

 

Thanks for your help!

 

--------------------------

John Wismar

Alldata Technology

916-478-3296

 

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using MetadataService to specify the default media type

Avi Flax
On Thu, Jan 19, 2012 at 05:20, Jerome Louvel <[hidden email]> wrote:

> The proper/standard way in HTTP to do this is to correctly set the
> preferences of your clients (via the “Accept” header typically)… Otherwise,
> the order of the annotated methods declaration might be taken into account
> by Restlet when deciding how to dispatch the method call, but I wouldn’t say
> it is a safe bet to solely rely on this default behavior.
>
> You could customize the ConnegService attached to your parent application to
> force the variant when client preferences are not explicitly given
> (MediaType.ALL), or plug a custom filter in the routing chain to enforce
> your policy.

Jerome,

I’m using 2.0, and I need a way to set the default variant of my
resources. I’m frustrated because I’d think this’d be a common need
and it really should be easier and clearer how to do this. I need to
support requests which don’t include an Accept header, and I need to
be able to set the default variant concisely on a resource-by-resource
basis — not in a centralized Service or Filter.

With the resource I’m working on now, I first tried to just use a
single annotation:

@Get(“html|xhtml”)
public Representation getRep(Variant variant) { … }

I assumed that when a request didn’t include an Accept header, the
conneg algorithm would take into account the order specified and use
html as the default. Unfortunately it does not — for some reason,
xhtml is chosen as the default.

Unsurprisingly, the same is true if I use two separate methods:

@Get(“html”)
public Representation getHtml() { … }

@Get(“xhtml”)
public Representation getXhtml() { … }

IIRC, in Restlet 1 this was fully supported — the first variant passed
to getVariants().add() was considered the default. I still need this
functionality.

I don’t know if it’s too late to change this for 2.0 (I’d love to
submit a patch…) but I’d at least like to see this improved for 2.1 —
I think the order specified in the annotation parameter should be
significant, with the first one specified used as the default.

For now, I’m not even sure how I’m going to make this work in the
resource I’m working on today — I might just do something hacky like
this:

if (acceptHeader != null &&
acceptHeader.contains("application/xhtml+xml") && !
acceptHeader.contains("text/html"))
    representation.setMediaType(MediaType.APPLICATION_XHTML);

Thanks,
Avi

Avi Flax » Arc90 » http://arc90.com
Kindling » Innovation through Collaboration » http://kindlingapp.com
Readability » Enjoy Reading, Support Writing » http://readability.com

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2916957
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using MetadataService to specify the default media type

Avi Flax
Ping?

On Wed, Feb 1, 2012 at 12:05, Avi Flax <[hidden email]> wrote:

> Jerome,
>
> I’m using 2.0, and I need a way to set the default variant of my
> resources. I’m frustrated because I’d think this’d be a common need
> and it really should be easier and clearer how to do this. I need to
> support requests which don’t include an Accept header, and I need to
> be able to set the default variant concisely on a resource-by-resource
> basis — not in a centralized Service or Filter.
>
> With the resource I’m working on now, I first tried to just use a
> single annotation:
>
> @Get(“html|xhtml”)
> public Representation getRep(Variant variant) { … }
>
> I assumed that when a request didn’t include an Accept header, the
> conneg algorithm would take into account the order specified and use
> html as the default. Unfortunately it does not — for some reason,
> xhtml is chosen as the default.
>
> Unsurprisingly, the same is true if I use two separate methods:
>
> @Get(“html”)
> public Representation getHtml() { … }
>
> @Get(“xhtml”)
> public Representation getXhtml() { … }
>
> IIRC, in Restlet 1 this was fully supported — the first variant passed
> to getVariants().add() was considered the default. I still need this
> functionality.
>
> I don’t know if it’s too late to change this for 2.0 (I’d love to
> submit a patch…) but I’d at least like to see this improved for 2.1 —
> I think the order specified in the annotation parameter should be
> significant, with the first one specified used as the default.
>
> For now, I’m not even sure how I’m going to make this work in the
> resource I’m working on today — I might just do something hacky like
> this:
>
> if (acceptHeader != null &&
> acceptHeader.contains("application/xhtml+xml") && !
> acceptHeader.contains("text/html"))
>    representation.setMediaType(MediaType.APPLICATION_XHTML);
>
> Thanks,
> Avi

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2922447
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Using MetadataService to specify the default media type

Jerome Louvel-2
Hi Avi,

Sorry for the delay. We'll look at this issue tomorrow, this doesn't look right indeed.

Best regards,
Jerome
--
http://www.restlet.org
http://twitter.com/#!/jlouvel


-----Message d'origine-----
De : Avi Flax [mailto:[hidden email]]
Envoyé : mardi 14 février 2012 20:17
À : [hidden email]
Objet : Re: Using MetadataService to specify the default media type

Ping?

On Wed, Feb 1, 2012 at 12:05, Avi Flax <[hidden email]> wrote:

> Jerome,
>
> I’m using 2.0, and I need a way to set the default variant of my
> resources. I’m frustrated because I’d think this’d be a common need
> and it really should be easier and clearer how to do this. I need to
> support requests which don’t include an Accept header, and I need to
> be able to set the default variant concisely on a resource-by-resource
> basis — not in a centralized Service or Filter.
>
> With the resource I’m working on now, I first tried to just use a
> single annotation:
>
> @Get(“html|xhtml”)
> public Representation getRep(Variant variant) { … }
>
> I assumed that when a request didn’t include an Accept header, the
> conneg algorithm would take into account the order specified and use
> html as the default. Unfortunately it does not — for some reason,
> xhtml is chosen as the default.
>
> Unsurprisingly, the same is true if I use two separate methods:
>
> @Get(“html”)
> public Representation getHtml() { … }
>
> @Get(“xhtml”)
> public Representation getXhtml() { … }
>
> IIRC, in Restlet 1 this was fully supported — the first variant passed
> to getVariants().add() was considered the default. I still need this
> functionality.
>
> I don’t know if it’s too late to change this for 2.0 (I’d love to
> submit a patch…) but I’d at least like to see this improved for 2.1 —
> I think the order specified in the annotation parameter should be
> significant, with the first one specified used as the default.
>
> For now, I’m not even sure how I’m going to make this work in the
> resource I’m working on today — I might just do something hacky like
> this:
>
> if (acceptHeader != null &&
> acceptHeader.contains("application/xhtml+xml") && !
> acceptHeader.contains("text/html"))
>    representation.setMediaType(MediaType.APPLICATION_XHTML);
>
> Thanks,
> Avi

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2922447

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2925111
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using MetadataService to specify the default media type

Thierry Boileau
In reply to this post by Avi Flax
Hello Avi,

I've made some tests using Restlet 2.0 and 2.1. From what I notice, in this case, the order is not significant.
I get the "xhtml" representation instead of the "html" one in both cases : @Get(“html|xhtml”) and @Get(“xhtml|html”)

Here is my explanation : "html" is a shortcut for "text/html" and "xhtml" stands for "application/xhtml+xml".
When the client provides no preference, then the default one set on the MetadataService is applied : by default "application/octet-stream".
The curent score algorithm gives a better affinity between "application/xhtml+xml" and "application/octet-stream" than between "text/html" and "application/octet-stream", because of "application/"... The scores are very low : 0.0006 and 0.0003 but the difference is real.

Good news anyway, you can set the default media type of the application's MetadataService to a neutral one : "*/*" :
getMetadataService().setDefaultMediaType(MediaType.ALL);

In this case, the order is significant, once again.

Best regards,
Thierry Boileau


> The proper/standard way in HTTP to do this is to correctly set the
> preferences of your clients (via the “Accept” header typically)… Otherwise,
> the order of the annotated methods declaration might be taken into account
> by Restlet when deciding how to dispatch the method call, but I wouldn’t say
> it is a safe bet to solely rely on this default behavior.
>
> You could customize the ConnegService attached to your parent application to
> force the variant when client preferences are not explicitly given
> (MediaType.ALL), or plug a custom filter in the routing chain to enforce
> your policy.

Jerome,

I’m using 2.0, and I need a way to set the default variant of my
resources. I’m frustrated because I’d think this’d be a common need
and it really should be easier and clearer how to do this. I need to
support requests which don’t include an Accept header, and I need to
be able to set the default variant concisely on a resource-by-resource
basis — not in a centralized Service or Filter.

With the resource I’m working on now, I first tried to just use a
single annotation:

@Get(“html|xhtml”)
public Representation getRep(Variant variant) { … }

I assumed that when a request didn’t include an Accept header, the
conneg algorithm would take into account the order specified and use
html as the default. Unfortunately it does not — for some reason,
xhtml is chosen as the default.

Unsurprisingly, the same is true if I use two separate methods:

@Get(“html”)
public Representation getHtml() { … }

@Get(“xhtml”)
public Representation getXhtml() { … }

IIRC, in Restlet 1 this was fully supported — the first variant passed
to getVariants().add() was considered the default. I still need this
functionality.

I don’t know if it’s too late to change this for 2.0 (I’d love to
submit a patch…) but I’d at least like to see this improved for 2.1 —
I think the order specified in the annotation parameter should be
significant, with the first one specified used as the default.

For now, I’m not even sure how I’m going to make this work in the
resource I’m working on today — I might just do something hacky like
this:

if (acceptHeader != null &&
acceptHeader.contains("application/xhtml+xml") && !
acceptHeader.contains("text/html"))
   representation.setMediaType(MediaType.APPLICATION_XHTML);

Thanks,
Avi

Avi Flax » Arc90 » http://arc90.com
Kindling » Innovation through Collaboration » http://kindlingapp.com
Readability » Enjoy Reading, Support Writing » http://readability.com

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2916957

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Re: Using MetadataService to specify the default media type

Thierry Boileau-3
Hello all,

by the way, we've just fixed a bug in the 2.1 branch and 2.2 trunk regarding the choice of the right annotated method, when handling request's entities (such as @Put, not @Get).

Best  regards,
Thierry Boileau

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2928074
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using MetadataService to specify the default media type

Avi Flax
In reply to this post by Thierry Boileau
On Wed, Feb 22, 2012 at 05:48, Thierry Boileau
<[hidden email]> wrote:

> I've made some tests using Restlet 2.0 and 2.1. From what I notice, in this
> case, the order is not significant.
> I get the "xhtml" representation instead of the "html" one in both cases :
> @Get(“html|xhtml”) and @Get(“xhtml|html”)
>
> Here is my explanation : "html" is a shortcut for "text/html" and "xhtml"
> stands for "application/xhtml+xml".
> When the client provides no preference, then the default one set on the
> MetadataService is applied : by default "application/octet-stream".
> The curent score algorithm gives a better affinity between
> "application/xhtml+xml" and "application/octet-stream" than between
> "text/html" and "application/octet-stream", because of "application/"... The
> scores are very low : 0.0006 and 0.0003 but the difference is real.
>
> Good news anyway, you can set the default media type of the application's
> MetadataService to a neutral one : "*/*" :
> getMetadataService().setDefaultMediaType(MediaType.ALL);
>
> In this case, the order is significant, once again.

Thanks Thierry, this is very very helpful, I appreciate you looking into this.

First: I suggest we make MediaType.ALL the default in 2.1 and 2.2.

Second: I’ve made this change in my application, and it seemed to work
at first — but it turns out that the behavior of my resource, when I
don’t send an Accept header, has become unpredictable.

I have these two methods in my resource class:

@Get("html|xhtml")
public Representation getHtml(Variant variant)

and:

@Get("json")
public Representation getJson()

now that I’ve made this change, most of the time when I run my app and
make a request for this resource without the Accept header, I get back
a response with the Content-Type being text/html, which is what I want
and expect. However, sometimes when I start my app and make the
request, I get back a JSON response.

This is of course not acceptable; I need the behavior of my app to be
predictable and consistent. Unfortunately I can’t give you statistics
on how often this occurs; my app takes a long time to start up. Off
the top of my head, it seems to be around 20% of the time.

Can you suggest any theories for why this might be happening, and some
possible ways to prevent this from happening?

Thanks!
Avi

Avi Flax » Arc90 » http://arc90.com
Kindling » Innovation through Collaboration » http://kindlingapp.com
Readability » Enjoy Reading, Support Writing » http://readability.com

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2936716
Loading...