users@jersey.java.net

Re: [Jersey] JSONP Callback support

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 04 Feb 2009 11:30:21 +0100

On Feb 3, 2009, at 7:17 PM, 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?
>

The main body of the response is set on the
ContainerResponse.getEntity(). This is then serialized using a message
body writer.

Your JSONCallbackResponseAdapter can adapt the output stream "out" in
it's own output stream.

Although such adaption could check for a byte that is of the value '@'
and not write this value it is really not the right layer because you
do not know what the character encoding is. One way is in the
writeStatusAndHeaders to buffer the content, then in the finish method
to re-parse the JSON and using something like Jackson to filter out
the '@' characters.

Another alternative is of course to have a configuration option in the
JSON serialization. But this may effect the ability to consume such
JSON back to JAXB.

Out of curiosity what JSON clients are you using?

Paul.

> What would I need to change to remove '@' sign globally from the
> response?
>
> Thanks for your help.
>
> --
> Regards,
> Farrukh
>
> Web: http://www.wellfleetsoftware.com
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>