package com.ajah.servlet.filter; import java.io.IOException; import java.io.OutputStream; import java.util.logging.Level; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import lombok.extern.java.Log; import com.ajah.util.StringUtils; /** * Wraps a JSON response with a JSONP callback. * * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a * href="mailto:code@efsavage.com">code@efsavage.com</a>. */ @Log public class JSONPFilter extends BaseFilter { /** * Wraps a JSON response with a JSONP callback, if possible and appropriate. * * @see com.ajah.servlet.filter.BaseFilter#doFilter(javax.servlet.ServletRequest, * javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { final String callback = request.getParameter("callback"); if (StringUtils.isBlank(callback)) { log.finest("Not adding callback, no \"callback\" parameter specified"); // If there's no callback, do nothing. chain.doFilter(request, response); return; } try (final OutputStream out = response.getOutputStream()) { final GenericResponseWrapper wrapper = new GenericResponseWrapper((HttpServletResponse) response); chain.doFilter(request, wrapper); if ("application/json".equals(wrapper.getContentType()) || "jsonp".equals(request.getParameter("format"))) { // We've got a JSON response if (log.isLoggable(Level.FINEST)) { log.finest("Adding callback \"" + callback + "\" to " + wrapper.getData().length + " bytes"); } out.write(callback.getBytes()); out.write('('); out.write(wrapper.getData()); out.write(");".getBytes()); } else { if (log.isLoggable(Level.FINEST)) { log.finest("Not adding callback, response is not JSON (" + wrapper.getContentType() + ")"); } // It's not JSON, don't mess with it out.write(wrapper.getData()); } } } }