Posts Tagged Grails
Grails: UIPerformance update
Posted by Morten in Uncategorized on May 18, 2009
I posted a post a while back about encoding issues using the Grails UIPerformance plugin. The issue will be resolved in version 1.1.1 of the UIPerformance plugin.
Grails: Cutom Url-mappings not working
Posted by Morten in Uncategorized on April 27, 2009
I ran into another problem with Grails just now.
I’m starting to separate the REST implementation of my service. I wanted to keep the default generated behaviour of the Grails views, at least for now. But the interaction of the web-application is foremost using the REST api.
Thus I wanted to add Url mappings to a /rest/ “sub-directory” of the web-app. So I have all the rest functionality using the rest/ prefix. Thus I updated my Urlmappings as such:
static mappings = {
"/rest/ServiceProvider/$id?"(controller:"ServiceProvider", action="rest")
"/$controller/$action?/$id?" {
constraints {
// apply constraints here
}
}
}
There is a problem with this, I named my domain class with a capital letter. As such my controller also starts with a capital letter. Apparently the url-mappings can’t find my controller when its specified using a capital letter in the name. If I enter the domain-class name using lower-case letters in the url-mapping it works.
static mappings = {
"/rest/ServiceProvider/$id?"(controller:"serviceProvider", action="rest")
"/$controller/$action?/$id?" {
constraints {
// apply constraints here
}
}
}
Jira ticket: http://jira.codehaus.org/browse/GRAILS-4488
Update: I made some assumptions about the error that were untrue, you do not need to rename the controller to get the custom url-mappings to work. You just need to start the domain-class name with a lowercase letter.
Grails: Quicksheet
Posted by Morten in Uncategorized on April 25, 2009
I just stumbled on the Grails cheatsheet. If you haven’t checked it out, I can recommend it.
I wanted a list of available constraints, and this gives me fast access to just that and lots more.
Grails: Morph-deploy and the Mail plugin
Posted by Morten in Uncategorized on April 23, 2009
Ive just spent a few hours configuring the mail plugin and the morph-deploy plugin, based on the forum and blog posts around the net. Only to find out that there was no need.
The morph-deploy plugin version 0.1 along with Grails 1.1 and mail 0.5 works perfectly with Morph as far as I can see. The only issue is the _Events.Groovy file which I blogged about earlier.
Grails: Working with the mail plugin
Posted by Morten in Uncategorized on April 23, 2009
I just started working with the mail plugin. The idea is to finish the user registration scenario that Ive been working on.
Now working with the mail plugin in development requires me to have a SMTP server running locally.
I’m not really Interested in a real one, instead I basically just want on that says these are all the mails sent to me.
What I found was Dumpster, a nice little library that allows you to set up a mock mail server. It’s designed to be run with unit tests, but its really easy to write up a server that runs in the command line, printing all the messages received by the server.
Grails: Jetty and Character-encoding
Posted by Morten in Uncategorized on April 20, 2009
Im doing something not supported. I’m serving html files through my Grails web-app running Jetty. Simply I have some static pages that will not change. I want them served uncompiled. I use the resources-first plugin to help out with serving these html files.
The files are documentation, responses if you wish, for the user. I load them using Ajax to provide standard responses for some actions. The problem is that the responses are in Swedish. Jetty only serves them in ISO-8859-1, which is its standard configuration. According to this.
The issue I have is that I can’t change it. I can’t set a system variable to change the default encoding to UTF-8, not without having to do some programming. As a result, the easiest way for me to handle this issue is to change my HTML files to GSP files. This forces me to serve them through the Grails stack and thus demands somewhat more resources from my poor server.
I tried to see if I could configure the Jetty-server to use UTF-8 as a default encoding, but alas according to this documentation I can only change it for the URI and not the content, and the URI is already set to UTF-8.
If anyone finds out how to serve HTML through the same server as Grails but with the correct encoding let me know. Right now I have a work around that will work for the next 6 months.
Update: Apparently, hosting just HTML files with utf-8 encoding set on the file, works in the production environment. Thank you Mor.ph.
Grails: UI-Performance plugin – issue with encodings
Posted by Morten in Uncategorized on April 13, 2009
After getting the UI-performance plugin to work, I started to address an issue I got with charsets and my js files.
I have some Swedish messages in some of my JavaScript files, and as such they have Swedish characters. While I was branching them I managed to change the charset of the files somehow, so they weren’t UTF-8. Easy enough to fix. However, after fixing them the error still occurred in the production environment.
After some tracking it turns out that the bundling process of the UI-performance plugin works with the system default character encoding in some parts of the files, and with a specified encoding in another. Non-bundled files are OK. The missing code is in the ResourceVersionHelper.groovy file on line 357 to 364.
private void concatenate(List files, String name, String subdir, String ext, File stagingDir) {
new File(stagingDir, "$subdir/${name}.$ext").withWriter { writer ->
files.each { file ->
writer.write new File(stagingDir, "$subdir/${file}.$ext").text
writer.write '\n'
}
}
}
Fixing it could be like this, but adding the charset as a parameter will allow for better configuration.
private void concatenate(List files, String name, String subdir, String ext, File stagingDir) {
new File(stagingDir, "$subdir/${name}.$ext").withWriter( "utf-8", { writer ->
files.each { file ->
writer.write new File(stagingDir, "$subdir/${file}.$ext").getText('utf-8')
writer.write '\n'
}
})
}
Still nice work Burt.
Jira ticket: http://jira.codehaus.org/browse/GRAILSPLUGINS-1079
Update: This is resolved in version: 1.1.1 of the UI-Performance plugin
Grails: UI-performance plugin
Posted by Morten in Uncategorized on April 12, 2009
I installed the UI-performance plugin last night. Configured it to bundle my javascript code into a single compressed file. Did the same with my CSS files.
With everything bundled and compressed the size of the the page download is reduced from 485 Kb to 187 Kb.
I only had some minor configuration problems but those were just related to my own typos. Apart from that it all now works perfectly.
The plugin saves me the time it would take me to produce a build step to produce the same output, and it even does more than the initial idea for my own build step. Thank you Burt Beckwith for a job well done!
Grails: Issue with Morph Deploy plugin
Posted by Morten in Uncategorized on April 11, 2009
I ran into a problem with Grails again, this time its with the Morph deploy plugin. It turns out its nothing special.
The problem I ran into was the following error when I created my war-file for the application.
Error executing script War: No such property: stagingDir for class: _Events
There are some issues with the _Events.groovy file for the plugin. I found the solution to the problem here.
I spent some time looking for the directory however. Naively I assumed that the plugins installed for my project would be available in the project directory. It turns out they weren’t. They are located in an entirely different part of my system, my User directory.
This means I have to set up special handling for source-controlling the plugins. I want them source-controlled since they impact the behaviour of my application.
To be honest I found this to be a bit annoying.
Grails: Ajax Login using Basic Auth
Posted by Morten in Uncategorized on April 7, 2009
So I have my Grails environment setup. The point is to build a REST-service that will work as a back end to a highly dynamic JavaScript page. I chose Grails, since it builds on Hibernate and Spring.
Two frameworks Id like to examine for the purpose of seeing the differences between Castle and nHibernate in the .Net world.
Building domain-classes and having the represented as XML is straight forward in Grails, but I need to take care of the login scenario. If you’d like to know more about building REST web services with Grails, I recommend reading the Mastering Grails: RESTful Grails article. Login seems like a good place to start, to ensure that my domain-controllers can dictate login as I develop the domain.
Now Grails.org has a list of tutorials, one of them, focusing on Login. It’s a good beginners tutorial showing how to use interceptors to execute user verification before showing the actual view requested. For my scenario however it has a few problems. Lets use the tutorial as a start of point.
The problems I have with the solution is with the following code:
def checkUser() {
if(!session.user) {
// i.e. user not logged in
redirect(controller:'user',action:'login')
return false
}
}
For my scenario this has one problem, in two places. Its stateful. First of it always directs the user to the same place, of course it can be different per controller. I need it to simple say access denied.
def checkUser() {
if(!session.user) {
// i.e. user not logged in
response.sendError(401)
return false
}
}
The above code is changed to instead of redirecting the user, it simply sets the response code to Access Denied. Now there’s just one issue left, the session code.
I don’t want to use session, as it requires my server to remember each session, preferably I want the client to remember the state.
Another issue is that I want to use Mor.ph AppSpace, if I pay for the most basic of subscriptions at Mor.ph I get two Cube, i.e. two servers with a load balancers in front. As a result I can’t be sure that the same server will service the same client all the time.
If we instead choose to check for the logged in user using the authorization header. The state is always provided by the client, instead of keeping the state on the server.
def checkUser() {
if(!UserController.checkAuthorization(request, response)) {
// i.e. user not logged in
response.sendError(401)
return false
}
return true
}
I let the UserController do the checking of the user, using a static method. This will let me keep the authorization code in the same place I handle users to begin with. It also allows me to change the authorization method later by changing the code in the checkAuthorization method. We could use Dependency Injection here to inject a real instance of the UserController, or even better an object with the sole responsibility to check user access. However DI is out of scope for this post.
You can implement any way of checking the user login you want. If you want a simple solution and stick with the HTTP standard you could use Basic auth. Here is a good explaination of how to implement Basic auth for Grails. Another way is too use a cookie to hold authorization information.
For this example were just sending username:password in the authorization header. My final implementation will be Basic Auth with the password hashed to a checksum. The point of the hash is to never send plain-text password across the net.
Here is the checkAuthorization method in the UserController for this example.
static boolean checkAuthorization(HttpServletRequest request, HttpServletResponse response) {
def authString = request.getHeader('Authorization')
if (!authString) {
return false;
}
def credentials = authString.split(':')
if( credentials.length != 2 || credentials[0] == null || credentials[0] == "" || credentials[1] == "" || credentials[1] == null)
return false;
def user = User.findByEmailAndPassword(credentials[0], credentials[1])
if (user) {
return true;
}
return false;
}
Now we can create some JQuery based JavaScript code to handle login.
function RestClient() {
var self = this;
var auth;
function ShowLoginUI(afterLoginCallback) {
var dialog = document.createElement('div');
$(dialog).html("<table><tr><td>Email</td><td><input id='email' type='text'/></td></tr><tr><td>Password</td><td><input id='pass' type='password'/></td></tr></table>");
$(dialog).dialog({ buttons: {"Login": function() {
auth = $(this).find("#email").val() + ":" + $(this).find("#pass").val();
afterLoginCallback();
$(this).dialog("close");
}, "Cancel":function() {
$(this).dialog("close");
}}, modal:true});
}
this.Get = function(url) {
var data = null;
data = $.ajax({
url : url,
method : 'GET',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth);
}, cache : true,
error: function(request, textStatus, error) {
if (request.status == 401) {
ShowLoginUI(function() {
data = self.Get(url);
});
}
}});
return data;
};
}
The above code does Ajax Get-calls to the specified address. If the call failed due to Access Denied, it shows a login form and tries to execute the Ajax request again. The class remembers the authorization string, so as long as the user uses the same RestClient-object the state is maintained at the client side.
Ill leave instructions on how to wire up Grails with JQuery to someone else.
Here is a simple usage example:
var a = new RestClient();
$("#test").click(function() {
var data = a.Get("plant/create");
$(document).append(data);
});
Good luck writing scalable login scenarios using Ajax instead of page reloads.