users@jersey.java.net

Re: [Jersey] JSONP Callback support

From: Farrukh Najmi <farrukh_at_wellfleetsoftware.com>
Date: Tue, 03 Feb 2009 13:53:24 -0500

Here is the more complete code for my ResponseFilter. I would appreciate
any tips on how to remove all occurances of '@' sign from my response
within this filter. Thanks.

/**
 * ResponseFilter to implement JSONP Callback support.
 * See: http://en.wikipedia.org/wiki/JSON#JSONP
http://developer.yahoo.com/common/json.html#callbackparam
 *
 * @author najmi
 */
public class JSONCallbackResponseFilter implements ContainerResponseFilter {

    private static final Log LOG =
LogFactory.getLog(JSONCallbackResponseFilter.class);

    public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {

        MultivaluedMap<String, String> queryParamsMapMulti =
request.getQueryParameters();
        Map queryParamsMap =
RegistryRestInterface.convertMultiToSingleValueMap(queryParamsMapMulti);
        LOG.debug("JSONCallbackResponseFilter queryParamsMap=" +
queryParamsMap);
        String callback = (String) queryParamsMap.get("callback");
        LOG.debug("callback=" + callback);
        if (callback != null) {
            response.setContainerResponseWriter(new
JSONCallbackResponseAdapter(response.getContainerResponseWriter(),
callback));
        }
        return response;
    }

    /**
     *
     * See:
http://n2.nabble.com/-Filter--how-to-customize-context-body---td2116754.html
     */
    private static final class JSONCallbackResponseAdapter implements
ContainerResponseWriter {

        private final ContainerResponseWriter crw;
        private OutputStream out;
        private String callback;

        JSONCallbackResponseAdapter(ContainerResponseWriter crw, String
callback) {
            this.crw = crw;
            this.callback = callback;
        }

        public OutputStream writeStatusAndHeaders(long contentLength,
ContainerResponse response) throws IOException {
            out = crw.writeStatusAndHeaders(-1, response);

            out.write((this.callback + "(").getBytes());
            return out;
        }

        public void finish() throws IOException {
            out.write(")".getBytes());
        }
    }
}



Farrukh Najmi wrote:
> Paul Sandoz wrote:
>> On Feb 3, 2009, at 3:21 AM, Farrukh Najmi wrote:
>>
>>>> <servlet>
>>>> <servlet-name>Registry REST Interface</servlet-name>
>>>>
>>>> <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
>>>>
>>>> <init-param>
>>>>
>>>> <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
>>>>
>>>>
>>>> <param-value>xxx.SomeClass.JSONCallbackResponseFilter</param-value>
>>>> </init-param>
>>>> <load-on-startup>4</load-on-startup>
>>>> </servlet>
>>>>
>>>> What I am finding is that the ResponseFilter is never being called.
>>>>
>>>> Why would that be?
>>>>
>>> Apparently it has something to do with the
>>> JSONCallbackResponseFilter being a nested class. Once I made it a
>>> top level class all is well. I am all set on the workaround. Thanks.
>>>
>>
>> You are not using the correct fully qualified name for an inner
>> class, it needs to be:
>>
>> xxx.SomeClass$JSONCallbackResponseFilter
>>
>
> Thank Paul for pointing out my mistake. The workaround is working now
> but I have a different issue.
>
> The use of '@' sign in resulting JSON as described by BadgerFish is
> causing a downstream problem for me as the toolkit I am using to
> process JSON does not like it. So I need to fix my ResponseFilter to
> remove '@' sign in the JSON output.
>
> Here is what my adapter class looks like:
>
> /**
> *
> * See:
> http://n2.nabble.com/-Filter--how-to-customize-context-body---td2116754.html
>
> */
> private static final class JSONCallbackResponseAdapter implements
> ContainerResponseWriter {
>
> private final ContainerResponseWriter crw;
> private OutputStream out;
> private String callback;
>
> JSONCallbackResponseAdapter(ContainerResponseWriter crw, String
> callback) {
> this.crw = crw;
> this.callback = callback;
> }
>
> public OutputStream writeStatusAndHeaders(long contentLength,
> ContainerResponse response) throws IOException {
> out = crw.writeStatusAndHeaders(-1, response);
>
> out.write((this.callback + "(").getBytes());
> return out;
> }
>
> public void finish() throws IOException {
> out.write(")".getBytes());
> }
> }
>
> I do not quite understand the above code originally from you. Where
> does the main body of the response get injected taht I need to filter?
>
> What would I need to change to remove '@' sign globally from the
> response?
>
> Thanks for your help.
>


-- 
Regards,
Farrukh
Web: http://www.wellfleetsoftware.com