Friday, September 23, 2011

CORS filter for Java applications

Hi there, in today's installment we're going to allow Ajax calls from other domains to be answered and accepted by browsers.

The what

This thing (completely forgotten by many) is called Cross Origin Resource Sharing and works with standard Ajax requests your browser can send. You can read about it in depth on Wikipedia or on the http://enable-cors.org/ site.

The how

Let's get to the meat - shall we? On the http://enable-cors.org/ site there are many recipes for all kind of servers and they respective configuration but what if you'd like to enable CORS just for a part of your application? If you're lucky enough and you're coding your application in Java then there is a standard mechanism to do just that! It's called filters.
Here's the most simple way of implementing CORS response headers:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CORSFilter implements Filter {

	public CORSFilter() { }

	public void init(FilterConfig fConfig) throws ServletException { }

	public void destroy() {	}

	public void doFilter(
		ServletRequest request, ServletResponse response, 
		FilterChain chain) throws IOException, ServletException {

		((HttpServletResponse)response).addHeader(
			"Access-Control-Allow-Origin", "*"
		);
		chain.doFilter(request, response);
	}
}
As you can see here all we're doing is adding the Access-Control-Allow-Origin header so that the browser can accept the response sent by server.

You can use this filter as follows in your web.xml:
<web-app>
	<filter>
		<filter-name>CORSFilter</filter-name>
		<filter-class>CORSFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CORSFilter</filter-name>
		<url-pattern>/api/*</url-pattern>
	</filter-mapping>
</web-app>

Have fun!

11 comments:

adam said...

I really like your post. Do you know how or have any tips on apply CORS to a grails 1.3.9 app?

Matthias Hryniszak said...

Grails _is_ Java - ergo: the procedure is the same.

adam said...

Grails is not java it is a web framework. Groovy is a language that uses the jvm so java can be used with groovy. What I am interested in how the cors filter would get applied to the grails framework as there is not a web.xml file that I can find. I guess I'll figure it out on my own.

Matthias Hryniszak said...

Grails is Java...

grails install-templates

and you'll find the web.xml file under src/templates/war/web.xml...

grails install-plugin webxml

and you'll have more synthetic control over the content of web.xml

.... so Grails is Java after all :)

adam said...

Cool, I shall try it. Thanks. However your solution does not mean grails is java. Grails is a framework and java is a programming language. Just like cakephp is a framework and php is a language. Just like django is a framework and python is a language and so on...

Daniel said...

I have a Grails project (2.1.0) with a problem this blog post aims to solve. I added the servlet filter/mapping to the web.xml per the suggestion here and (after installing templates) then added the Java file under src/java. Everything compiles and runs. But the response headers are still missing the CORS bit. Any thoughts on why this is? XMLHTTPRequests still fail (the server responds with a 503 HTTP error) and every other asset, when I introspect to see if the response header is there, doesn't have the header. Any ideas on how I can further troubleshoot this problem?

Matthias Hryniszak said...

If you could post your example project that causes this error we'd have a common ground in finding out what the issue is. Maybe on GitHub or BitBucket?

Unknown said...

You made my day.... this post is too helpful.. thanks a lot

HabibPlus said...

Thank you so much for this post! Saved me!

HabibPlus said...

Thank you so much for this great post!

Unknown said...

Hi! In case you need to translate your Java app, there's a good translation management platform that I recommend to try. https://poeditor.com/ has a collaborative nature, so you can work in teams for different translation projects.