users@jersey.java.net

Re: [Jersey] JSONP Callback support

From: Farrukh Najmi <farrukh_at_wellfleetsoftware.com>
Date: Mon, 02 Feb 2009 20:36:36 -0500

Farrukh Najmi wrote:
> Farrukh Najmi wrote:
>>
>> Hi Guys,
>>
>> I am in need of JSONP Callback support mentioned in this post:
>>
>> <http://n2.nabble.com/-Filter--how-to-customize-context-body---td2116754.html>
>>
>>
>> Has there been any progress on that front? Is an issue logged yet? Is
>> there a fix in svn yet?
>>
>> Please let me know. Thanks.
>>
>
> Just found the issue here:
>
> <https://jersey.dev.java.net/issues/show_bug.cgi?id=180>
>
> I would really appreciate some idea from dev team when this could be
> available in svn as it is a critical issue for me and likely many
> other folks. If it will be a while then I would be grateful if someone
> could expand a little on how to do the workaround suggest by Paul in
> cited thread above where an Adpater is used in a Response Filter. Thanks.
>

So I tried out the workaround suggested by Paul:

I implemented a ResponseFilter as follows. Note
JSONCallbackResponseFilter is "static final" class because it is nested
inside another class 'xxx.SomeClass':


    public static final class JSONCallbackResponseFilter implements
ContainerResponseFilter {

        public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {

            MultivaluedMap<String, String> queryParamsMapMulti =
request.getQueryParameters();
            Map queryParamsMap =
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());
            }
        }
    }

I have the following in my web.xml:

  <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?

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