How to get a JSONP response from Spring MVC
The best and easy way to do this is attach a filter to HTTP response.
Here is a working example for this
public class JsonpBoundryFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
@SuppressWarnings("unchecked")
Map<String, String[]> parms = httpRequest.getParameterMap();
if(parms.containsKey("callback")) {
OutputStream out = httpResponse.getOutputStream();
GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);
chain.doFilter(request, wrapper);
byte[] bytes1 = new String(parms.get("callback")[0] + "(").getBytes();
byte[] bytes2 = wrapper.getData();
byte[] bytes3 = new String(");").getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(bytes1.length + bytes2.length + bytes3.length);
byteBuffer.put(bytes1);
byteBuffer.put(bytes2);
byteBuffer.put(bytes3);
byte[] jsonpResponse = byteBuffer.array();
wrapper.setContentType("text/javascript;charset=UTF-8");
wrapper.setContentLength(jsonpResponse.length);
out.write(jsonpResponse);
out.close();
} else {
chain.doFilter(request, response);
}
}
public void destroy() {}
}
public class GenericResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream output;
private FilterServletOutputStream filterStream;
private PrintWriter printWriter;
private int contentLength;
private String contentType;
public GenericResponseWrapper(HttpServletResponse response) {
super(response);
output = new ByteArrayOutputStream();
filterStream = new FilterServletOutputStream(output);
printWriter = new PrintWriter(output, true);
}
public byte[] getData() {
return output.toByteArray();
}
public ServletOutputStream getOutputStream() {
return filterStream;
}
public PrintWriter getWriter() {
return printWriter;
}
public void setContentLength(int length) {
this.contentLength = length;
super.setContentLength(length);
}
public int getContentLength() {
return contentLength;
}
public void setContentType(String type) {
this.contentType = type;
super.setContentType(type);
}
public String getContentType() {
return contentType;
}
}
public class FilterServletOutputStream extends ServletOutputStream {
private DataOutputStream stream;
public FilterServletOutputStream(OutputStream output) {
stream = new DataOutputStream(output);
}
public void write(int b) throws IOException {
stream.write(b);
}
public void write(byte[] b) throws IOException {
stream.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
stream.write(b, off, len);
}
}
<filter>
<filter-name>jsonpCallbackFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>jsonpBroudryFilter</filter-name> // this name should be in your spring config
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/dispatch-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<bean id="jsonpCallbackFilter" class="com.....JsonpBoundryFilter" />
Sound easy............. :)
The best and easy way to do this is attach a filter to HTTP response.
Here is a working example for this
- Create a filter class and its supported utility classes
public class JsonpBoundryFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
@SuppressWarnings("unchecked")
Map<String, String[]> parms = httpRequest.getParameterMap();
if(parms.containsKey("callback")) {
OutputStream out = httpResponse.getOutputStream();
GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);
chain.doFilter(request, wrapper);
byte[] bytes1 = new String(parms.get("callback")[0] + "(").getBytes();
byte[] bytes2 = wrapper.getData();
byte[] bytes3 = new String(");").getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(bytes1.length + bytes2.length + bytes3.length);
byteBuffer.put(bytes1);
byteBuffer.put(bytes2);
byteBuffer.put(bytes3);
byte[] jsonpResponse = byteBuffer.array();
wrapper.setContentType("text/javascript;charset=UTF-8");
wrapper.setContentLength(jsonpResponse.length);
out.write(jsonpResponse);
out.close();
} else {
chain.doFilter(request, response);
}
}
public void destroy() {}
}
public class GenericResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream output;
private FilterServletOutputStream filterStream;
private PrintWriter printWriter;
private int contentLength;
private String contentType;
public GenericResponseWrapper(HttpServletResponse response) {
super(response);
output = new ByteArrayOutputStream();
filterStream = new FilterServletOutputStream(output);
printWriter = new PrintWriter(output, true);
}
public byte[] getData() {
return output.toByteArray();
}
public ServletOutputStream getOutputStream() {
return filterStream;
}
public PrintWriter getWriter() {
return printWriter;
}
public void setContentLength(int length) {
this.contentLength = length;
super.setContentLength(length);
}
public int getContentLength() {
return contentLength;
}
public void setContentType(String type) {
this.contentType = type;
super.setContentType(type);
}
public String getContentType() {
return contentType;
}
}
public class FilterServletOutputStream extends ServletOutputStream {
private DataOutputStream stream;
public FilterServletOutputStream(OutputStream output) {
stream = new DataOutputStream(output);
}
public void write(int b) throws IOException {
stream.write(b);
}
public void write(byte[] b) throws IOException {
stream.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
stream.write(b, off, len);
}
}
- Add the following configurations to your web.xml
<filter>
<filter-name>jsonpCallbackFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>jsonpBroudryFilter</filter-name> // this name should be in your spring config
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/dispatch-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
- Add following to your spring config as
<bean id="jsonpCallbackFilter" class="com.....JsonpBoundryFilter" />
Sound easy............. :)
No comments:
Post a Comment