I am upgrading a Spring Boot application to version 2.0 and Spring Framework to version 5.1.
The application currently uses Spring's built in JSONP support using AbstractJsonpResponseBodyAdvice.
@ControllerAdvice
public class JsonpControllerAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpControllerAdvice() {
super("jsonp");
}
}
However, JSONP support was deprecated in version 5.0.7 and removed in version 5.1 RC1. In addition, it's not feasible to switch to CORS at this time.
A final caveat is that the JavaScript callback method must begin with /**/
. For example (truncated):
/**/jQuery1720351297557893959_1567180700293(...)
I've tried using jsonp-filter but I am unable to configure the callback to include /**/
.
How do I create a custom Spring Boot JSONP filter with /**/
prepended to the callback?
Note: My example is similar to Spring Boot: Remove /**/ before JSONP callback function name. But I can't remove the /**/
because the existing frontend code expects it in the callback.
While you can't use jsonp-filter, you can define a simple filter based on it. For example:
@Component
public class JsonPFilter implements Filter {
@Override public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String callback = null;
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
callback = httpServletRequest.getParameter("jsonp");
}
if (callback != null) {
OutputStream out = response.getOutputStream();
out.write(String.format("/**/%s(", callback).getBytes());
chain.doFilter(request, response);
out.write(new JsonPResponseWrapper((HttpServletResponse) response).getData());
out.write(")".getBytes());
out.close();
} else {
chain.doFilter(request, response);
}
}
private static class JsonPResponseWrapper extends HttpServletResponseWrapper {
private JsonPResponseWrapper(HttpServletResponse response) {
super(response);
}
private byte[] getData() {
return new ByteArrayOutputStream().toByteArray();
}
}
}