Sumit Lohia <sumit.lohia <at> gmail.com> writes:
> 
> Jerome Louvel <contact <at> noelios.com> writes:
> 
(snipped previous messages about handling multiple representations of a
resource). 

Hi,

I have resources which have three potential representations: HTML, JSON
and XML. I would like these representations to be available all the time
but to be prioritised sensibly based on the client - e.g. HTML first,
then JSON and/or XML.

If I just make all the Variants available then some clients get the
'wrong' variant. Safari likes JSON and Firefox likes XML...

Is there an automated and elegant way to specify prioritisation? Here is
how I'm currently doing this in my Resource implementation:

    @Override
    public List<Variant> getVariants() {
        List<Variant> varients = super.getVariants();
        // TODO: does cover all web browser clients?
        if (doesClientAccept(MediaType.TEXT_HTML) ||
doesClientAccept(MediaType.ALL)) {
            varients.add(new Variant(MediaType.TEXT_HTML));
        } else {
            varients.add(new Variant(MediaType.APPLICATION_XML));
            varients.add(new Variant(MediaType.APPLICATION_JSON));
        }
        return varients;
    }

    @Override
    public Representation getRepresentation(Variant variant) {
        if (variant.getMediaType().equals(MediaType.TEXT_HTML)) {
            return getHtmlRepresentation(); // implemented elsewhere
        } else if (variant.getMediaType()
                                                
.equals(MediaType.APPLICATION_JSON)) {
            return getJsonRepresentation(); // implemented elsewhere
        } else if (variant.getMediaType()
                                                
.equals(MediaType.APPLICATION_XML)) {
            return getDomRepresentation(); // implemented elsewhere
        } else {
            return super.getRepresentation(variant);
        }
    }

    // this ignores Preference 'quality'
    public boolean doesClientAccept(MediaType mediaType) {
        List<Preference<MediaType>> mediaTypePrefs =
                getRequest().getClientInfo().getAcceptedMediaTypes();
        for (Preference<MediaType> mediaTypePref : mediaTypePrefs) {
            if (mediaTypePref.getMetadata().equals(mediaType)) {
                return true;
            }
        }
        return false;
    }

I have this code in a base class so it's not really in the way but I think
it's probably not the best implementation. Any ideas?

Is there a need for a priority number on Variant? so I could do the
following:

varients.add(new Variant(MediaType.TEXT_HTML, 1.0)); // first
varients.add(new Variant(MediaType.APPLICATION_XML, 0.5)); // = second
varients.add(new Variant(MediaType.APPLICATION_JSON, 0.5)); // = second

Also: getVariants() gets called three times per request - is this expected?

Best regards,

Dig.



Reply via email to