package org.jboss.resteasy.plugins.providers.jackson;

import java.io.IOException;
import java.io.OutputStreamWriter;

import javax.ws.rs.ConstrainedTo;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

import org.codehaus.jackson.map.ObjectMapper;
import org.jboss.resteasy.core.MediaTypeMap;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;

JSONP is an alternative to normal AJAX requests. Instead of using a XMLHttpRequest a script tag is added to the DOM. The browser will call the corresponding URL and download the JavaScript. The server creates a response which looks like a method call. The parameter is the body of the request. The name of the method to call is normally passed as query parameter. The method has to be present in the current JavaScript environment.

Jackson JSON processor can produce such an response. This interceptor checks if the media type is a JavaScript one if there is a query parameter with the method name. The default name of this query parameter is "callback". So this interceptor is compatible with jQuery.

Author:Holger Morch
Version:$Revision: 1 $
Deprecated:Use resteasy-jackson2-provider
/** * <p> * JSONP is an alternative to normal AJAX requests. Instead of using a XMLHttpRequest a script tag is added to the DOM. * The browser will call the corresponding URL and download the JavaScript. The server creates a response which looks like a * method call. The parameter is the body of the request. The name of the method to call is normally passed as query parameter. * The method has to be present in the current JavaScript environment. * </p> * <p> * Jackson JSON processor can produce such an response. This interceptor checks if the media type is a JavaScript one if there is a query * parameter with the method name. The default name of this query parameter is "callback". So this interceptor is compatible with * <a href="http://api.jquery.com/jQuery.ajax/">jQuery</a>. * </p> * * @author <a href="mailto:holger.morch@nokia.com">Holger Morch</a> * @version $Revision: 1 $ * @deprecated Use resteasy-jackson2-provider */
@Provider @ConstrainedTo(RuntimeType.SERVER) @Deprecated public class JacksonJsonpInterceptor implements WriterInterceptor{
"text/javascript" media type. Default media type of script tags.
/** * "text/javascript" media type. Default media type of script tags. */
public static final MediaType TEXT_JAVASCRIPT_MEDIA_TYPE = new MediaType("text", "javascript");
"application/javascript" media type.
/** * "application/javascript" media type. */
public static final MediaType APPLICATION_JAVASCRIPT_MEDIA_TYPE = new MediaType("application", "javascript");
"text/json" media type.
/** * "text/json" media type. */
public static final MediaType TEXT_JSON_TYPE = new MediaType("text", "json");
"application/*+json" media type.
/** * "application/*+json" media type. */
public static final MediaType APPLICATION_PLUS_JSON_TYPE = new MediaType("application", "*+json");
Default name of the query parameter with the method name.
/** * Default name of the query parameter with the method name. */
public static final String DEFAULT_CALLBACK_QUERY_PARAMETER = "callback";
If response media type is one of this jsonp response may be created.
/** * If response media type is one of this jsonp response may be created. */
public static final MediaTypeMap<String> jsonpCompatibleMediaTypes = new MediaTypeMap<String>();
Default ObjectMapper for type resolution. Used if none is provided by Providers.
/** * Default {@link ObjectMapper} for type resolution. Used if none is provided by {@link Providers}. */
protected static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper(); static { jsonpCompatibleMediaTypes.add(MediaType.APPLICATION_JSON_TYPE , MediaType.APPLICATION_JSON_TYPE.toString()); jsonpCompatibleMediaTypes.add(APPLICATION_JAVASCRIPT_MEDIA_TYPE, APPLICATION_JAVASCRIPT_MEDIA_TYPE.toString()); jsonpCompatibleMediaTypes.add(APPLICATION_PLUS_JSON_TYPE , APPLICATION_PLUS_JSON_TYPE.toString()); jsonpCompatibleMediaTypes.add(TEXT_JSON_TYPE , TEXT_JSON_TYPE.toString()); jsonpCompatibleMediaTypes.add(TEXT_JAVASCRIPT_MEDIA_TYPE , TEXT_JAVASCRIPT_MEDIA_TYPE.toString()); } private UriInfo uri; private String callbackQueryParameter = DEFAULT_CALLBACK_QUERY_PARAMETER;
The ObjectMapper used to create typing information.
/** * The {@link ObjectMapper} used to create typing information. */
protected ObjectMapper objectMapper;
The Providers used to retrieve the objectMapper from.
/** * The {@link Providers} used to retrieve the {@link #objectMapper} from. */
protected Providers providers;
{@inheritDoc}
/** * {@inheritDoc} */
@Override public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException { LogMessages.LOGGER.debugf("Interceptor : %s, Method : aroundWriteTo", getClass().getName()); String function = uri.getQueryParameters().getFirst(callbackQueryParameter); if (function != null && !function.trim().isEmpty() && !jsonpCompatibleMediaTypes.getPossible(context.getMediaType()).isEmpty()){ OutputStreamWriter writer = new OutputStreamWriter(context.getOutputStream()); writer.write(function + "("); writer.flush(); context.proceed(); writer.write(")"); writer.flush(); } else { context.proceed(); } }
Search for an ObjectMapper for the given class and mediaType
Params:
  • type – the Class to serialize
  • mediaType – the response MediaType
Returns:the ObjectMapper
/** * Search for an {@link ObjectMapper} for the given class and mediaType * * @param type the {@link Class} to serialize * @param mediaType the response {@link MediaType} * @return the {@link ObjectMapper} */
protected ObjectMapper getObjectMapper(Class<?> type, MediaType mediaType) { if (objectMapper != null) { return objectMapper; } if (providers != null) { ContextResolver<ObjectMapper> resolver = providers.getContextResolver(ObjectMapper.class, mediaType); if (resolver == null) { resolver = providers.getContextResolver(ObjectMapper.class, null); } if (resolver != null) { return resolver.getContext(type); } } return DEFAULT_MAPPER; }
Setter used by RESTeasy to provide the UriInfo.
Params:
  • uri – the uri to set
/** * Setter used by RESTeasy to provide the {@link UriInfo}. * * @param uri the uri to set */
@Context public void setUri(UriInfo uri) { this.uri = uri; }
Setter used by RESTeasy to provide the Providers
Params:
  • providers –
/** * Setter used by RESTeasy to provide the {@link Providers} * * @param providers */
@Context public void setProviders(Providers providers) { this.providers = providers; }
Set an fix ObjectMapper. If this is not set Providers are used for lookup. If there are is none too, use a default one.
Params:
  • objectMapper –
/** * Set an fix {@link ObjectMapper}. If this is not set {@link Providers} are used for lookup. If there are is none too, use a default one. * * @param objectMapper */
public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; }
Get the name of the query parameter which contains the JavaScript method name. Default: callback.
Returns:the callbackQueryParameter
/** * Get the name of the query parameter which contains the JavaScript method name. Default: callback. * * @return the callbackQueryParameter */
public String getCallbackQueryParameter() { return callbackQueryParameter; }
Set callback query parameter.
Params:
  • callbackQueryParameter – the callbackQueryParameter to set
See Also:
  • getCallbackQueryParameter()
/** * Set callback query parameter. * * @see #getCallbackQueryParameter() * @param callbackQueryParameter the callbackQueryParameter to set */
public void setCallbackQueryParameter(String callbackQueryParameter) { this.callbackQueryParameter = callbackQueryParameter; } }