Cross-Origin Resource Sharing with Play! framework
I was trying to develop with play! framework for a 3-tier achitecture. So I run 2 applications on the same machine but on 2 differents ports (the front on 9010 and the back application on 9011 that has access to the database).
Trying to call WS services (with JSON format) from the front controllers is transparent.
public static void index() {
HttpResponse response = WS.url("http://localhost:9011/api/accounts").get();
JsonElement json = response.getJson();
render(json);
}
But trying to make dynamic pages with JQuery querying from the front page the the back controller, the results were blocked due tothe Same Origin Policy. So I had to specify the Cross-Origin Resource Sharing on the back controller.
Here is the code to add on the controller of the backapplication : this will add the header to allow the caller to access the service :
public static void listAccounts() {
List<Account> accounts = Account.findAll();
Http.Header hd = new Http.Header();
hd.name = "Access-Control-Allow-Origin";
hd.values = new ArrayList<String>();
hd.values.add("http://localhost:9010");
Http.Response.current().headers.put("Access-Control-Allow-Origin",hd);
renderJSON(accounts);
}
You can sepecify a list of domains to accept as origin, or set it to * to allow all domains to call your service.
And the JQuery call :
$("#accounts").click(function(){
$.getJSON('http://localhost:9011/api/accounts', function(accounts) {
var items = [];
$.each(accounts, function(title, acc) {
console.log(acc);
$("#results").append('<p>'+acc.number+'</p>');
});
});
});
You can generalize the CORS setting with the @Before annotation, so all your services in a class will be accessible :
@Before
public static void setCORS() {
Http.Header hd = new Http.Header();
hd.name = "Access-Control-Allow-Origin";
hd.values = new ArrayList<String>();
hd.values.add("http://localhost:9010");
Http.Response.current().headers.put("Access-Control-Allow-Origin",hd);
}
Then your services coding in the controller is wery simple :
public static void listAccounts() {
List<Account> accounts = Account.findAll();
renderJSON(accounts);
}