Monday, November 10, 2008
Thursday, October 23, 2008
Creating RESTful services with Jersey and Groovy
It's been a while since I have put anything of substance on here, so I thought I would get back to it. I've been doing a lot of development with Groovy as of late, which I absolutely love. I wanted to combine that with another API that I really like, Jersey. Jersey is the open source JAX-RS (JSR 311) Reference Implementation for building RESTful Web services. So, for a simple service to create I decided on an Announcements service. This service when invoked would look for a file located in the User Home directory and create some HTML to return that would get rendered in the browser. This example also shows why I might want to use Groovy and Jersey together, as I will leverage Groovy's MarkupBuilder to generate the HTML that gets returned. I won't get into the details of how to setup Jersey as they have lots of samples that you can find here, and instead I'll just jump right in to what the source code would look like for my announcement service.
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces
@Path("/announcements")
class AnnouncementService {
def announcements = "announcements.txt"
def errorReadingFileText = " - Error reading Announcements, Announcement File may not exist."
def noAnnouncementsText = " - No Announcements for Today"
@GET
@Produces (value=["text/html"])
String getHtmlResponse() {
// Return some cliched textual content
return getAnnouncements()
}
String getAnnouncements() {
def announcement = new File(System.getProperty("user.home") + File.separator + announcements)
def writer = new StringWriter()
def result = new groovy.xml.MarkupBuilder(writer);
result.html {
body {
h1(align: "center", "As of ${date()}")
table(width: "100%", height: "100%") {
td {
if (!announcement.exists()) {
tr(errorReadingFileText)
} else if (announcement.text.length() <= 0) {
tr(noAnnouncementsText)
} else {
announcement?.eachLine {
tr(" - $it")
}
}
}
}
}
}
return writer.toString()
}
}As you can see from the code above that we annotate our class with the
@Path annotation. This basically defines your jersey resource. So if you wanted to invoke this resource you URL would be something like http://localhost:8080/sample/announcements where sample is the name of your war you deployed to your application server. In the code you can also see that our method getHtmlResponse() has been annotated with @GET which tells Jersey to call this method when the HTTP Request is a GET Request. So given the same URL noted above, you could type that into a browser and hit enter and it will invoke the announcement resource with a GET request and invoke our method. One other thing to note is the @Produces annotation. This annotation defines the mime type to return your result. In our case we want the result to render as html so we set the type to text/html. This annotation is one that I had to do a little diffrent with Groovy. In Java the annotation would look like @Produces("text/html"), whereas in Groovy I have to specifically call out the value property and enclose the value in brackets like this, @Produces (value=["text/html"]). If I didn't enclose the property in the proper way I got this error when compiling:Annotation list attributes must use Groovy notation [el1, el2]
The good thing is my IDE (I was using Netbeans) caught this before compile time, and I refrenced this issue to figure out how to get around it.
So, as you can see from my source code that the bulk of the work is taking place in the getAnnouncements() method. This was the reason that I wanted to use Groovy, I could very easily read a file, and based on the content create some html markup that would be returned to the browser. Not much to discuss here, except that MarkupBuilder is very cool. Alright, I think that's it, Good Luck. One last thing is I used Jersey 1.0 and Groovy 1.5.6 to work this example.
Posted by
Chad Gallemore
at
10:24:00 PM
4
comments
Links to this post
Thursday, June 26, 2008
Rapid Web Application Prototypes with Maven and Groovy
Utilizing both Maven and Groovy you can rapidly prototype web apps, and in this blog I'll walk you through exactly how to do that. First we are going to create a simple Maven web app project using the Maven Web App Archetype. If you don't have Maven installed already, go ahead and install it. Now let's create a directory called sandbox, and cd into that directory. Now let's create our project by issuing the following command:mvn archetype:generateWhen prompted to choose a number enter 18 (The Java web application archetype) and hit enter. Next you will be prompted for the groupId, enter com.sample and hit enter, for the artifactId enter sample and hit enter, for the version enter 1.0 and hit enter, and for the package name enter com.sample and hit enter. Confirm you project by entering "Y" and hitting enter. Once finsihed you will have a maven project ready to go for deployment. You should see a sample diretory that was created in /sandbox with a pom.xml file. The pom.xml file is what we will look at next.
Next we need to add the dependency for Groovy to our pom, as well as the Maven Groovy Plugin. We do this by adding the following inside the <build> element in the parent pom:
<plugins>
<plugin>
<groupId>org.codehaus.mojo.groovy</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
Now that we have the Groovy Plugin added, lets add the Groovy dependency to the pom as well by adding it inside the <dependencies> element of the pom:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.5.6</version>
</dependency>
Ok, let's save all that and make sure we can build everything. From /sandbox/sample issue the following command:mvn clean install
You should now have a successful build, and you could actually deploy the war that gets created (in /sandbox/sample/target you will have sample.war) to an application server such as JBoss. Ok, lets get onto the cool stuff. Groovy has a concept that lets you write normal Java servlets in Groovy, called Groovlets. Groovlets are really easy to work with and have some nice features like implicit variables (e.g. request and response which are bound to the ServletRequest and ServletResponse). So what we are going to do is configure our webapp so that it can handle Groovlets and then create our first Groovlet. We are first going to edit our web.xml which is located at /sandbox/sample/src/main/webapp/WEB-INF/, go ahead an open that up and add the following between the <web-app> elements:
<servlet>
<servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GroovyTemplate</servlet-name>
<servlet-class>groovy.servlet.TemplateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GroovyServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GroovyTemplate</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
This configures your webapp to compile your .groovy files to bytecode and execute your script when called. Next we need to create our Groovlet and then we are done. So, in /sandbox/sample/src/main/webapp create a file called Sample.groovy. We are going to create a simple Groovlet that accepts an HTTP GET request and has a parameter called username. We will process the request and just print out the response. So, go ahead and open up the Sample.groovy file you opened and add the following:
def username = request.getParameter("username")
println "Hello ${username}"
That's it. Rember that the request variable is implicit, meaning it's already bound to the ServletRequest and ready for use. Now we can compile our war, and deploy it to your favorite application server and you are ready to roll. Once deployed navigate to http://localhost:8080/sample/Sample.groovy?username=Chad in your web browser and you should see the print out "Hello Chad".This is a really nice way to rapidly prototype webapps. I first started looking into this when I needed a servlet that could access the file system and return XML based off my lookup. Obiously using Groovy's nice features that have been added to the JDK for working with Files, and the MarkupBuilder, this task was trivial. Give it a spin and let me know what you think.
Posted by
Chad Gallemore
at
3:44:00 PM
4
comments
Links to this post
Monday, June 9, 2008
Deploying Jersey REST services to Weblogic
I recently had some trouble deploying a REST service using Jersey to Weblogic, specifically Weblogic 9.2. This had me stumped for quite a while as I could deploy my war to JBoss and Tomcat and it worked fine. Finally with an assist from the mailing list I was able to get past the problem and get the war to deploy. As Paul noted, the problem was that the default class scanning technique is not portable across servlet implmentations, so I needed to add the following to my web.xml (after the <servlet-class> element):
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*';' separated package names*</param-value>
</init-param>
This tells Jersey to use the package scanning instead of the class path scanning. Now all you have to do is insert your package names in the last param value (replace the *';' with your package name(s) seperated by ';').
For more detail on this issue see the issue that was filed with Jersey here.
Posted by
Chad Gallemore
at
10:36:00 AM
3
comments
Links to this post
Thursday, May 29, 2008
Groovy SQL - That was easy

I got the chance today to get my hands dirty with GSQL (Groovy's Built in support for SQL), and I must say that it was rather easy. What I needed to do was connect to an embedded Derby database, parse a file, and populate the table with the results. Not to hard right. So, here is what my data looked like in the file I needed to parse:
2008/04/06,pubsubproxy,6166,4061
2008/04/07,pubsubproxy,6166,4061
2008/04/08,pubsubproxy,6170,4061
2008/04/09,pubsubproxy,6170,4061
2008/04/10,pubsubproxy,6170,4061
2008/04/11,pubsubproxy,6170,4061
2008/04/12,pubsubproxy,6170,4061
2008/04/13,pubsubproxy,6170,4061
2008/04/14,pubsubproxy,6170,4061
The best part about this was as I read each line in the file I added the data to the dataset for the table I was populating. The following shows a quick example of how to do this:
static parseData(path) {
println("parsing data for the following path: $path")
setDBSystemDir()
def loc = new File(path)
//Get an instance to the derby database
def sql = Sql.newInstance("jdbc:derby:dashboard;create=true", "org.apache.derby.jdbc.EmbeddedDriver")
//For Each line in the file, split the line based on the comma
loc.splitEachLine(',') {fields ->
def pid = fields[1]
def locResult = Double.parseDouble(fields[2])
def tloc = Double.parseDouble(fields[3])
def timeStamp = getDate(fields[0])
//Get the linesofcode dataset from the database
def ds = sql.dataSet("linesofcode")
//Add the properties from the current line in the file to the dataset.
ds.add(
PID:pid,
TIMESTAMP:timeStamp,
LOC:locResult,
TLOC:tloc,
)
}
println "Done Parsing Data"
}
So as you can see the first thing I do is get a new instance to my database:def sql = Sql.newInstance("jdbc:derby:dashboard;create=true", "org.apache.derby.jdbc.EmbeddedDriver")
Next is the best part. I loop over each line in the file, splitting the line based of the "," and then dive right in poplulating my dataset with
ds.add().That was easy right? I thought so.
Posted by
Chad Gallemore
at
3:52:00 PM
2
comments
Links to this post


